Coverage Report

Created: 2019-05-19 14:56

/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
14.5k
void wasm::debugWrite(uint64_t Offset, const Twine &Msg) {
23
14.5k
  LLVM_DEBUG(dbgs() << format("  | %08lld: ", Offset) << Msg << "\n");
24
14.5k
}
25
26
6.99k
void wasm::writeUleb128(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
27
6.99k
  debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
28
6.99k
  encodeULEB128(Number, OS);
29
6.99k
}
30
31
664
void wasm::writeSleb128(raw_ostream &OS, int32_t Number, const Twine &Msg) {
32
664
  debugWrite(OS.tell(), Msg + "[" + utohexstr(Number) + "]");
33
664
  encodeSLEB128(Number, OS);
34
664
}
35
36
void wasm::writeBytes(raw_ostream &OS, const char *Bytes, size_t Count,
37
162
                      const Twine &Msg) {
38
162
  debugWrite(OS.tell(), Msg + " [data[" + Twine(Count) + "]]");
39
162
  OS.write(Bytes, Count);
40
162
}
41
42
1.69k
void wasm::writeStr(raw_ostream &OS, StringRef String, const Twine &Msg) {
43
1.69k
  debugWrite(OS.tell(),
44
1.69k
             Msg + " [str[" + Twine(String.size()) + "]: " + String + "]");
45
1.69k
  encodeULEB128(String.size(), OS);
46
1.69k
  OS.write(String.data(), String.size());
47
1.69k
}
48
49
3.63k
void wasm::writeU8(raw_ostream &OS, uint8_t Byte, const Twine &Msg) {
50
3.63k
  debugWrite(OS.tell(), Msg + " [0x" + utohexstr(Byte) + "]");
51
3.63k
  OS << Byte;
52
3.63k
}
53
54
162
void wasm::writeU32(raw_ostream &OS, uint32_t Number, const Twine &Msg) {
55
162
  debugWrite(OS.tell(), Msg + "[0x" + utohexstr(Number) + "]");
56
162
  support::endian::write(OS, Number, support::little);
57
162
}
58
59
588
void wasm::writeValueType(raw_ostream &OS, ValType Type, const Twine &Msg) {
60
588
  writeU8(OS, static_cast<uint8_t>(Type),
61
588
          Msg + "[type: " + toString(Type) + "]");
62
588
}
63
64
201
void wasm::writeSig(raw_ostream &OS, const WasmSignature &Sig) {
65
201
  writeU8(OS, WASM_TYPE_FUNC, "signature type");
66
201
  writeUleb128(OS, Sig.Params.size(), "param Count");
67
201
  for (ValType ParamType : Sig.Params) {
68
50
    writeValueType(OS, ParamType, "param type");
69
50
  }
70
201
  writeUleb128(OS, Sig.Returns.size(), "result Count");
71
201
  if (Sig.Returns.size()) {
72
78
    writeValueType(OS, Sig.Returns[0], "result type");
73
78
  }
74
201
}
75
76
506
void wasm::writeInitExpr(raw_ostream &OS, const WasmInitExpr &InitExpr) {
77
506
  writeU8(OS, InitExpr.Opcode, "opcode");
78
506
  switch (InitExpr.Opcode) {
79
506
  case WASM_OPCODE_I32_CONST:
80
498
    writeSleb128(OS, InitExpr.Value.Int32, "literal (i32)");
81
498
    break;
82
506
  case WASM_OPCODE_I64_CONST:
83
3
    writeSleb128(OS, InitExpr.Value.Int64, "literal (i64)");
84
3
    break;
85
506
  case WASM_OPCODE_GLOBAL_GET:
86
5
    writeUleb128(OS, InitExpr.Value.Global, "literal (global index)");
87
5
    break;
88
506
  default:
89
0
    fatal("unknown opcode in init expr: " + Twine(InitExpr.Opcode));
90
506
  }
91
506
  writeU8(OS, WASM_OPCODE_END, "opcode:end");
92
506
}
93
94
169
void wasm::writeLimits(raw_ostream &OS, const WasmLimits &Limits) {
95
169
  writeU8(OS, Limits.Flags, "limits flags");
96
169
  writeUleb128(OS, Limits.Initial, "limits initial");
97
169
  if (Limits.Flags & WASM_LIMITS_FLAG_HAS_MAX)
98
158
    writeUleb128(OS, Limits.Maximum, "limits max");
99
169
}
100
101
460
void wasm::writeGlobalType(raw_ostream &OS, const WasmGlobalType &Type) {
102
460
  // TODO: Update WasmGlobalType to use ValType and remove this cast.
103
460
  writeValueType(OS, ValType(Type.Type), "global type");
104
460
  writeU8(OS, Type.Mutable, "global mutable");
105
460
}
106
107
434
void wasm::writeGlobal(raw_ostream &OS, const WasmGlobal &Global) {
108
434
  writeGlobalType(OS, Global.Type);
109
434
  writeInitExpr(OS, Global.InitExpr);
110
434
}
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
162
void wasm::writeTableType(raw_ostream &OS, const llvm::wasm::WasmTable &Type) {
122
162
  writeU8(OS, WASM_TYPE_FUNCREF, "table type");
123
162
  writeLimits(OS, Type.Limits);
124
162
}
125
126
61
void wasm::writeImport(raw_ostream &OS, const WasmImport &Import) {
127
61
  writeStr(OS, Import.Module, "import module name");
128
61
  writeStr(OS, Import.Field, "import field name");
129
61
  writeU8(OS, Import.Kind, "import kind");
130
61
  switch (Import.Kind) {
131
61
  case WASM_EXTERNAL_FUNCTION:
132
22
    writeUleb128(OS, Import.SigIndex, "import sig index");
133
22
    break;
134
61
  case WASM_EXTERNAL_GLOBAL:
135
26
    writeGlobalType(OS, Import.Global);
136
26
    break;
137
61
  case WASM_EXTERNAL_EVENT:
138
0
    writeEventType(OS, Import.Event);
139
0
    break;
140
61
  case WASM_EXTERNAL_MEMORY:
141
7
    writeLimits(OS, Import.Memory);
142
7
    break;
143
61
  case WASM_EXTERNAL_TABLE:
144
6
    writeTableType(OS, Import.Table);
145
6
    break;
146
61
  default:
147
0
    fatal("unsupported import type: " + Twine(Import.Kind));
148
61
  }
149
61
}
150
151
600
void wasm::writeExport(raw_ostream &OS, const WasmExport &Export) {
152
600
  writeStr(OS, Export.Name, "export name");
153
600
  writeU8(OS, Export.Kind, "export kind");
154
600
  switch (Export.Kind) {
155
600
  case WASM_EXTERNAL_FUNCTION:
156
171
    writeUleb128(OS, Export.Index, "function index");
157
171
    break;
158
600
  case WASM_EXTERNAL_GLOBAL:
159
293
    writeUleb128(OS, Export.Index, "global index");
160
293
    break;
161
600
  case WASM_EXTERNAL_MEMORY:
162
135
    writeUleb128(OS, Export.Index, "memory index");
163
135
    break;
164
600
  case WASM_EXTERNAL_TABLE:
165
1
    writeUleb128(OS, Export.Index, "table index");
166
1
    break;
167
600
  default:
168
0
    fatal("unsupported export type: " + Twine(Export.Kind));
169
600
  }
170
600
}
171
} // namespace lld
172
173
619
std::string lld::toString(ValType Type) {
174
619
  switch (Type) {
175
619
  case ValType::I32:
176
568
    return "i32";
177
619
  case ValType::I64:
178
31
    return "i64";
179
619
  case ValType::F32:
180
17
    return "f32";
181
619
  case ValType::F64:
182
3
    return "f64";
183
619
  case ValType::V128:
184
0
    return "v128";
185
619
  case ValType::EXCEPT_REF:
186
0
    return "except_ref";
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
}