Coverage Report

Created: 2018-10-20 12:32

/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
using namespace lld::wasm;
21
22
361
static const char *valueTypeToString(ValType Type) {
23
361
  switch (Type) {
24
361
  case wasm::ValType::I32:
25
324
    return "i32";
26
361
  case wasm::ValType::I64:
27
25
    return "i64";
28
361
  case wasm::ValType::F32:
29
9
    return "f32";
30
361
  case wasm::ValType::F64:
31
3
    return "f64";
32
361
  default:
33
0
    llvm_unreachable("invalid value type");
34
361
  }
35
361
}
36
37
namespace lld {
38
39
10.7k
void wasm::debugWrite(uint64_t Offset, const Twine &Msg) {
40
10.7k
  LLVM_DEBUG(dbgs() << format("  | %08lld: ", Offset) << Msg << "\n");
41
10.7k
}
42
43
5.65k
void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
44
5.65k
  debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
45
5.65k
  encodeULEB128(Number, OS);
46
5.65k
}
47
48
464
void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg) {
49
464
  debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
50
464
  encodeSLEB128(Number, OS);
51
464
}
52
53
void wasm::writeBytes(raw_ostream &OS, const char *Bytes, size_t Count,
54
99
                      const Twine &Msg) {
55
99
  debugWrite(OS.tell(), Msg + " [data[" + Twine(Count) + "]]");
56
99
  OS.write(Bytes, Count);
57
99
}
58
59
1.29k
void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) {
60
1.29k
  debugWrite(OS.tell(),
61
1.29k
             Msg + " [str[" + Twine(String.size()) + "]: " + String + "]");
62
1.29k
  encodeULEB128(String.size(), OS);
63
1.29k
  OS.write(String.data(), String.size());
64
1.29k
}
65
66
2.28k
void wasm::writeU8(raw_ostream &OS, uint8_t Byte, const Twine &Msg) {
67
2.28k
  debugWrite(OS.tell(), Msg + " [0x" + utohexstr(Byte) + "]");
68
2.28k
  OS << Byte;
69
2.28k
}
70
71
99
void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
72
99
  debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]");
73
99
  support::endian::write(OS, Number, support::little);
74
99
}
75
76
361
void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) {
77
361
  writeU8(OS, static_cast<uint8_t>(Type),
78
361
          Msg + "[type: " + valueTypeToString(Type) + "]");
79
361
}
80
81
167
void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {
82
167
  writeU8(OS, WASM_TYPE_FUNC, "signature type");
83
167
  writeUleb128(OS, Sig.Params.size(), "param Count");
84
167
  for (ValType ParamType : Sig.Params) {
85
34
    writeValueType(OS, ParamType, "param type");
86
34
  }
87
167
  writeUleb128(OS, Sig.Returns.size(), "result Count");
88
167
  if (Sig.Returns.size()) {
89
63
    writeValueType(OS, Sig.Returns[0], "result type");
90
63
  }
91
167
}
92
93
271
void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {
94
271
  writeU8(OS, InitExpr.Opcode, "opcode");
95
271
  switch (InitExpr.Opcode) {
96
271
  case WASM_OPCODE_I32_CONST:
97
268
    writeSleb128(OS, InitExpr.Value.Int32, "literal (i32)");
98
268
    break;
99
271
  case WASM_OPCODE_I64_CONST:
100
3
    writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
101
3
    break;
102
271
  case WASM_OPCODE_GET_GLOBAL:
103
0
    writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
104
0
    break;
105
271
  default:
106
0
    fatal("unknown opcode in init expr: " + Twine(InitExpr.Opcode));
107
271
  }
108
271
  writeU8(OS, WASM_OPCODE_END, "opcode:end");
109
271
}
110
111
101
void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) {
112
101
  writeU8(OS, Limits.Flags, "limits flags");
113
101
  writeUleb128(OS, Limits.Initial, "limits initial");
114
101
  if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX)
115
100
    writeUleb128(OS, Limits.Maximum, "limits max");
116
101
}
117
118
264
void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) {
119
264
  // TODO: Update WasmGlobalType to use ValType and remove this cast.
120
264
  writeValueType(OS, ValType(Type.Type), "global type");
121
264
  writeU8(OS, Type.Mutable, "global mutable");
122
264
}
123
124
257
void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) {
125
257
  writeGlobalType(OS, Global.Type);
126
257
  writeInitExpr(OS, Global.InitExpr);
127
257
}
128
129
99
void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {
130
99
  writeU8(OS, WASM_TYPE_ANYFUNC, "table type");
131
99
  writeLimits(OS, Type.Limits);
132
99
}
133
134
26
void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) {
135
26
  writeStr(OS, Import.Module, "import module name");
136
26
  writeStr(OS, Import.Field, "import field name");
137
26
  writeU8(OS, Import.Kind, "import kind");
138
26
  switch (Import.Kind) {
139
26
  case WASM_EXTERNAL_FUNCTION:
140
16
    writeUleb128(OS, Import.SigIndex, "import sig index");
141
16
    break;
142
26
  case WASM_EXTERNAL_GLOBAL:
143
7
    writeGlobalType(OS, Import.Global);
144
7
    break;
145
26
  case WASM_EXTERNAL_MEMORY:
146
2
    writeLimits(OS, Import.Memory);
147
2
    break;
148
26
  case WASM_EXTERNAL_TABLE:
149
1
    writeTableType(OS, Import.Table);
150
1
    break;
151
26
  default:
152
0
    fatal("unsupported import type: " + Twine(Import.Kind));
153
26
  }
154
26
}
155
156
391
void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) {
157
391
  writeStr(OS, Export.Name, "export name");
158
391
  writeU8(OS, Export.Kind, "export kind");
159
391
  switch (Export.Kind) {
160
391
  case WASM_EXTERNAL_FUNCTION:
161
138
    writeUleb128(OS, Export.Index, "function index");
162
138
    break;
163
391
  case WASM_EXTERNAL_GLOBAL:
164
172
    writeUleb128(OS, Export.Index, "global index");
165
172
    break;
166
391
  case WASM_EXTERNAL_MEMORY:
167
80
    writeUleb128(OS, Export.Index, "memory index");
168
80
    break;
169
391
  case WASM_EXTERNAL_TABLE:
170
1
    writeUleb128(OS, Export.Index, "table index");
171
1
    break;
172
391
  default:
173
0
    fatal("unsupported export type: " + Twine(Export.Kind));
174
391
  }
175
391
}
176
} // namespace lld
177
178
29
std::string lld::toString(ValType Type) {
179
29
  switch (Type) {
180
29
  case ValType::I32:
181
19
    return "I32";
182
29
  case ValType::I64:
183
6
    return "I64";
184
29
  case ValType::F32:
185
4
    return "F32";
186
29
  case ValType::F64:
187
0
    return "F64";
188
29
  case ValType::V128:
189
0
    return "V128";
190
29
  case ValType::EXCEPT_REF:
191
0
    return "except_ref";
192
0
  }
193
0
  llvm_unreachable("Invalid wasm::ValType");
194
0
}
195
196
14
std::string lld::toString(const WasmSignature &Sig) {
197
14
  SmallString<128> S("(");
198
17
  for (ValType Type : Sig.Params) {
199
17
    if (S.size() != 1)
200
8
      S += ", ";
201
17
    S += toString(Type);
202
17
  }
203
14
  S += ") -> ";
204
14
  if (Sig.Returns.size() == 0)
205
2
    S += "void";
206
12
  else
207
12
    S += toString(Sig.Returns[0]);
208
14
  return S.str();
209
14
}
210
211
0
std::string lld::toString(const WasmGlobalType &Sig) {
212
0
  return (Sig.Mutable ? "var " : "const ") +
213
0
         toString(static_cast<ValType>(Sig.Type));
214
0
}