Coverage Report

Created: 2019-07-24 05:18

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