Coverage Report

Created: 2018-08-19 21:11

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