Coverage Report

Created: 2019-01-18 03:29

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/lld/wasm/WriterUtils.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- WriterUtils.cpp ----------------------------------------------------===//
2
//
3
//                             The LLVM Linker
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
10
#include "WriterUtils.h"
11
#include "lld/Common/ErrorHandler.h"
12
#include "llvm/Support/Debug.h"
13
#include "llvm/Support/EndianStream.h"
14
#include "llvm/Support/LEB128.h"
15
16
#define DEBUG_TYPE "lld"
17
18
using namespace llvm;
19
using namespace llvm::wasm;
20
21
namespace lld {
22
23
11.3k
void wasm::debugWrite(uint64_t Offset, const Twine &Msg) {
24
11.3k
  LLVM_DEBUG(dbgs() << format("  | %08lld: ", Offset) << Msg << "\n");
25
11.3k
}
26
27
5.83k
void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
28
5.83k
  debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
29
5.83k
  encodeULEB128(Number, OS);
30
5.83k
}
31
32
487
void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg) {
33
487
  debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
34
487
  encodeSLEB128(Number, OS);
35
487
}
36
37
void wasm::writeBytes(raw_ostream &OS, const char *Bytes, size_t Count,
38
106
                      const Twine &Msg) {
39
106
  debugWrite(OS.tell(), Msg + " [data[" + Twine(Count) + "]]");
40
106
  OS.write(Bytes, Count);
41
106
}
42
43
1.36k
void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) {
44
1.36k
  debugWrite(OS.tell(),
45
1.36k
             Msg + " [str[" + Twine(String.size()) + "]: " + String + "]");
46
1.36k
  encodeULEB128(String.size(), OS);
47
1.36k
  OS.write(String.data(), String.size());
48
1.36k
}
49
50
2.53k
void wasm::writeU8(raw_ostream &OS, uint8_t Byte, const Twine &Msg) {
51
2.53k
  debugWrite(OS.tell(), Msg + " [0x" + utohexstr(Byte) + "]");
52
2.53k
  OS << Byte;
53
2.53k
}
54
55
106
void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
56
106
  debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]");
57
106
  support::endian::write(OS, Number, support::little);
58
106
}
59
60
386
void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) {
61
386
  writeU8(OS, static_cast<uint8_t>(Type),
62
386
          Msg + "[type: " + toString(Type) + "]");
63
386
}
64
65
176
void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {
66
176
  writeU8(OS, WASM_TYPE_FUNC, "signature type");
67
176
  writeUleb128(OS, Sig.Params.size(), "param Count");
68
176
  for (ValType ParamType : Sig.Params) {
69
36
    writeValueType(OS, ParamType, "param type");
70
36
  }
71
176
  writeUleb128(OS, Sig.Returns.size(), "result Count");
72
176
  if (Sig.Returns.size()) {
73
63
    writeValueType(OS, Sig.Returns[0], "result type");
74
63
  }
75
176
}
76
77
341
void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {
78
341
  writeU8(OS, InitExpr.Opcode, "opcode");
79
341
  switch (InitExpr.Opcode) {
80
341
  case WASM_OPCODE_I32_CONST:
81
336
    writeSleb128(OS, InitExpr.Value.Int32, "literal (i32)");
82
336
    break;
83
341
  case WASM_OPCODE_I64_CONST:
84
3
    writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
85
3
    break;
86
341
  case WASM_OPCODE_GLOBAL_GET:
87
2
    writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
88
2
    break;
89
341
  default:
90
0
    fatal("unknown opcode in init expr: " + Twine(InitExpr.Opcode));
91
341
  }
92
341
  writeU8(OS, WASM_OPCODE_END, "opcode:end");
93
341
}
94
95
109
void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) {
96
109
  writeU8(OS, Limits.Flags, "limits flags");
97
109
  writeUleb128(OS, Limits.Initial, "limits initial");
98
109
  if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX)
99
106
    writeUleb128(OS, Limits.Maximum, "limits max");
100
109
}
101
102
287
void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) {
103
287
  // TODO: Update WasmGlobalType to use ValType and remove this cast.
104
287
  writeValueType(OS, ValType(Type.Type), "global type");
105
287
  writeU8(OS, Type.Mutable, "global mutable");
106
287
}
107
108
277
void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) {
109
277
  writeGlobalType(OS, Global.Type);
110
277
  writeInitExpr(OS, Global.InitExpr);
111
277
}
112
113
1
void wasm::writeEventType(raw_ostream &OS, const WasmEventType &Type) {
114
1
  writeUleb128(OS, Type.Attribute, "event attribute");
115
1
  writeUleb128(OS, Type.SigIndex, "sig index");
116
1
}
117
118
1
void wasm::writeEvent(raw_ostream &OS, const WasmEvent &Event) {
119
1
  writeEventType(OS, Event.Type);
120
1
}
121
122
106
void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {
123
106
  writeU8(OS, WASM_TYPE_FUNCREF, "table type");
124
106
  writeLimits(OS, Type.Limits);
125
106
}
126
127
33
void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) {
128
33
  writeStr(OS, Import.Module, "import module name");
129
33
  writeStr(OS, Import.Field, "import field name");
130
33
  writeU8(OS, Import.Kind, "import kind");
131
33
  switch (Import.Kind) {
132
33
  case WASM_EXTERNAL_FUNCTION:
133
18
    writeUleb128(OS, Import.SigIndex, "import sig index");
134
18
    break;
135
33
  case WASM_EXTERNAL_GLOBAL:
136
10
    writeGlobalType(OS, Import.Global);
137
10
    break;
138
33
  case WASM_EXTERNAL_EVENT:
139
0
    writeEventType(OS, Import.Event);
140
0
    break;
141
33
  case WASM_EXTERNAL_MEMORY:
142
3
    writeLimits(OS, Import.Memory);
143
3
    break;
144
33
  case WASM_EXTERNAL_TABLE:
145
2
    writeTableType(OS, Import.Table);
146
2
    break;
147
33
  default:
148
0
    fatal("unsupported import type: " + Twine(Import.Kind));
149
33
  }
150
33
}
151
152
417
void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) {
153
417
  writeStr(OS, Export.Name, "export name");
154
417
  writeU8(OS, Export.Kind, "export kind");
155
417
  switch (Export.Kind) {
156
417
  case WASM_EXTERNAL_FUNCTION:
157
144
    writeUleb128(OS, Export.Index, "function index");
158
144
    break;
159
417
  case WASM_EXTERNAL_GLOBAL:
160
186
    writeUleb128(OS, Export.Index, "global index");
161
186
    break;
162
417
  case WASM_EXTERNAL_MEMORY:
163
86
    writeUleb128(OS, Export.Index, "memory index");
164
86
    break;
165
417
  case WASM_EXTERNAL_TABLE:
166
1
    writeUleb128(OS, Export.Index, "table index");
167
1
    break;
168
417
  default:
169
0
    fatal("unsupported export type: " + Twine(Export.Kind));
170
417
  }
171
417
}
172
} // namespace lld
173
174
415
std::string lld::toString(ValType Type) {
175
415
  switch (Type) {
176
415
  case ValType::I32:
177
368
    return "i32";
178
415
  case ValType::I64:
179
31
    return "i64";
180
415
  case ValType::F32:
181
13
    return "f32";
182
415
  case ValType::F64:
183
3
    return "f64";
184
415
  case ValType::V128:
185
0
    return "v128";
186
415
  case ValType::EXCEPT_REF:
187
0
    return "except_ref";
188
0
  }
189
0
  llvm_unreachable("Invalid wasm::ValType");
190
0
}
191
192
14
std::string lld::toString(const WasmSignature &Sig) {
193
14
  SmallString<128> S("(");
194
17
  for (ValType Type : Sig.Params) {
195
17
    if (S.size() != 1)
196
8
      S += ", ";
197
17
    S += toString(Type);
198
17
  }
199
14
  S += ") -> ";
200
14
  if (Sig.Returns.size() == 0)
201
2
    S += "void";
202
12
  else
203
12
    S += toString(Sig.Returns[0]);
204
14
  return S.str();
205
14
}
206
207
0
std::string lld::toString(const WasmGlobalType &Type) {
208
0
  return (Type.Mutable ? "var " : "const ") +
209
0
         toString(static_cast<ValType>(Type.Type));
210
0
}
211
212
0
std::string lld::toString(const WasmEventType &Type) {
213
0
  if (Type.Attribute == WASM_EVENT_ATTRIBUTE_EXCEPTION)
214
0
    return "exception";
215
0
  return "unknown";
216
0
}