brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.2 KiB · b78c354 Raw
271 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "WriterUtils.h"10#include "lld/Common/ErrorHandler.h"11#include "llvm/ADT/StringExtras.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 18using namespace llvm;19using namespace llvm::wasm;20 21namespace lld {22std::string toString(ValType type) {23  switch (type) {24  case ValType::I32:25    return "i32";26  case ValType::I64:27    return "i64";28  case ValType::F32:29    return "f32";30  case ValType::F64:31    return "f64";32  case ValType::V128:33    return "v128";34  case ValType::FUNCREF:35    return "funcref";36  case ValType::EXTERNREF:37    return "externref";38  case ValType::EXNREF:39    return "exnref";40  case ValType::OTHERREF:41    return "otherref";42  }43  llvm_unreachable("Invalid wasm::ValType");44}45 46std::string toString(const WasmSignature &sig) {47  SmallString<128> s("(");48  for (ValType type : sig.Params) {49    if (s.size() != 1)50      s += ", ";51    s += toString(type);52  }53  s += ") -> ";54  if (sig.Returns.empty())55    s += "void";56  else57    s += toString(sig.Returns[0]);58  return std::string(s);59}60 61std::string toString(const WasmGlobalType &type) {62  return (type.Mutable ? "var " : "const ") +63         toString(static_cast<ValType>(type.Type));64}65 66static std::string toString(const llvm::wasm::WasmLimits &limits) {67  std::string ret;68  ret += "flags=0x" + std::to_string(limits.Flags);69  ret += "; min=" + std::to_string(limits.Minimum);70  if (limits.Flags & WASM_LIMITS_FLAG_HAS_MAX)71    ret += "; max=" + std::to_string(limits.Maximum);72  if (limits.Flags & WASM_LIMITS_FLAG_HAS_PAGE_SIZE)73    ret += "; pagesize=" + std::to_string(limits.PageSize);74  return ret;75}76 77std::string toString(const WasmTableType &type) {78  return "type=" + toString(static_cast<ValType>(type.ElemType)) +79         "; limits=[" + toString(type.Limits) + "]";80}81 82namespace wasm {83#ifdef LLVM_DEBUG84void debugWrite(uint64_t offset, const Twine &msg) {85  LLVM_DEBUG(dbgs() << format("  | %08lld: ", offset) << msg << "\n");86}87#endif88 89void writeUleb128(raw_ostream &os, uint64_t number, const Twine &msg) {90  debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]");91  encodeULEB128(number, os);92}93 94void writeSleb128(raw_ostream &os, int64_t number, const Twine &msg) {95  debugWrite(os.tell(), msg + "[" + utohexstr(number) + "]");96  encodeSLEB128(number, os);97}98 99void writeBytes(raw_ostream &os, const char *bytes, size_t count,100                      const Twine &msg) {101  debugWrite(os.tell(), msg + " [data[" + Twine(count) + "]]");102  os.write(bytes, count);103}104 105void writeStr(raw_ostream &os, StringRef string, const Twine &msg) {106  debugWrite(os.tell(),107             msg + " [str[" + Twine(string.size()) + "]: " + string + "]");108  encodeULEB128(string.size(), os);109  os.write(string.data(), string.size());110}111 112void writeU8(raw_ostream &os, uint8_t byte, const Twine &msg) {113  debugWrite(os.tell(), msg + " [0x" + utohexstr(byte) + "]");114  os << byte;115}116 117void writeU32(raw_ostream &os, uint32_t number, const Twine &msg) {118  debugWrite(os.tell(), msg + "[0x" + utohexstr(number) + "]");119  support::endian::write(os, number, llvm::endianness::little);120}121 122void writeU64(raw_ostream &os, uint64_t number, const Twine &msg) {123  debugWrite(os.tell(), msg + "[0x" + utohexstr(number) + "]");124  support::endian::write(os, number, llvm::endianness::little);125}126 127void writeValueType(raw_ostream &os, ValType type, const Twine &msg) {128  writeU8(os, static_cast<uint8_t>(type),129          msg + "[type: " + toString(type) + "]");130}131 132void writeSig(raw_ostream &os, const WasmSignature &sig) {133  writeU8(os, WASM_TYPE_FUNC, "signature type");134  writeUleb128(os, sig.Params.size(), "param Count");135  for (ValType paramType : sig.Params) {136    writeValueType(os, paramType, "param type");137  }138  writeUleb128(os, sig.Returns.size(), "result Count");139  for (ValType returnType : sig.Returns) {140    writeValueType(os, returnType, "result type");141  }142}143 144void writeI32Const(raw_ostream &os, int32_t number, const Twine &msg) {145  writeU8(os, WASM_OPCODE_I32_CONST, "i32.const");146  writeSleb128(os, number, msg);147}148 149void writeI64Const(raw_ostream &os, int64_t number, const Twine &msg) {150  writeU8(os, WASM_OPCODE_I64_CONST, "i64.const");151  writeSleb128(os, number, msg);152}153 154void writePtrConst(raw_ostream &os, int64_t number, bool is64,155                   const Twine &msg) {156  if (is64)157    writeI64Const(os, number, msg);158  else159    writeI32Const(os, static_cast<int32_t>(number), msg);160}161 162void writeMemArg(raw_ostream &os, uint32_t alignment, uint64_t offset) {163  writeUleb128(os, alignment, "alignment");164  writeUleb128(os, offset, "offset");165}166 167void writeInitExpr(raw_ostream &os, const WasmInitExpr &initExpr) {168  assert(!initExpr.Extended);169  writeInitExprMVP(os, initExpr.Inst);170}171 172void writeInitExprMVP(raw_ostream &os, const WasmInitExprMVP &initExpr) {173  writeU8(os, initExpr.Opcode, "opcode");174  switch (initExpr.Opcode) {175  case WASM_OPCODE_I32_CONST:176    writeSleb128(os, initExpr.Value.Int32, "literal (i32)");177    break;178  case WASM_OPCODE_I64_CONST:179    writeSleb128(os, initExpr.Value.Int64, "literal (i64)");180    break;181  case WASM_OPCODE_F32_CONST:182    writeU32(os, initExpr.Value.Float32, "literal (f32)");183    break;184  case WASM_OPCODE_F64_CONST:185    writeU64(os, initExpr.Value.Float64, "literal (f64)");186    break;187  case WASM_OPCODE_GLOBAL_GET:188    writeUleb128(os, initExpr.Value.Global, "literal (global index)");189    break;190  case WASM_OPCODE_REF_NULL:191    writeValueType(os, ValType::EXTERNREF, "literal (externref type)");192    break;193  default:194    fatal("unknown opcode in init expr: " + Twine(initExpr.Opcode));195  }196  writeU8(os, WASM_OPCODE_END, "opcode:end");197}198 199void writeLimits(raw_ostream &os, const WasmLimits &limits) {200  writeU8(os, limits.Flags, "limits flags");201  writeUleb128(os, limits.Minimum, "limits min");202  if (limits.Flags & WASM_LIMITS_FLAG_HAS_MAX)203    writeUleb128(os, limits.Maximum, "limits max");204  if (limits.Flags & WASM_LIMITS_FLAG_HAS_PAGE_SIZE)205    writeUleb128(os, llvm::Log2_64(limits.PageSize), "page size");206}207 208void writeGlobalType(raw_ostream &os, const WasmGlobalType &type) {209  // TODO: Update WasmGlobalType to use ValType and remove this cast.210  writeValueType(os, ValType(type.Type), "global type");211  writeU8(os, type.Mutable, "global mutable");212}213 214void writeTableType(raw_ostream &os, const WasmTableType &type) {215  writeValueType(os, ValType(type.ElemType), "table type");216  writeLimits(os, type.Limits);217}218 219void writeImport(raw_ostream &os, const WasmImport &import) {220  writeStr(os, import.Module, "import module name");221  writeStr(os, import.Field, "import field name");222  writeU8(os, import.Kind, "import kind");223  switch (import.Kind) {224  case WASM_EXTERNAL_FUNCTION:225    writeUleb128(os, import.SigIndex, "import sig index");226    break;227  case WASM_EXTERNAL_GLOBAL:228    writeGlobalType(os, import.Global);229    break;230  case WASM_EXTERNAL_TAG:231    writeUleb128(os, 0, "tag attribute"); // Reserved "attribute" field232    writeUleb128(os, import.SigIndex, "import sig index");233    break;234  case WASM_EXTERNAL_MEMORY:235    writeLimits(os, import.Memory);236    break;237  case WASM_EXTERNAL_TABLE:238    writeTableType(os, import.Table);239    break;240  default:241    fatal("unsupported import type: " + Twine(import.Kind));242  }243}244 245void writeExport(raw_ostream &os, const WasmExport &export_) {246  writeStr(os, export_.Name, "export name");247  writeU8(os, export_.Kind, "export kind");248  switch (export_.Kind) {249  case WASM_EXTERNAL_FUNCTION:250    writeUleb128(os, export_.Index, "function index");251    break;252  case WASM_EXTERNAL_GLOBAL:253    writeUleb128(os, export_.Index, "global index");254    break;255  case WASM_EXTERNAL_TAG:256    writeUleb128(os, export_.Index, "tag index");257    break;258  case WASM_EXTERNAL_MEMORY:259    writeUleb128(os, export_.Index, "memory index");260    break;261  case WASM_EXTERNAL_TABLE:262    writeUleb128(os, export_.Index, "table index");263    break;264  default:265    fatal("unsupported export type: " + Twine(export_.Kind));266  }267}268 269} // namespace wasm270} // namespace lld271