diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-writer.cc | 230 |
1 files changed, 111 insertions, 119 deletions
diff --git a/src/binary-writer.cc b/src/binary-writer.cc index dca0c464..856fee3b 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -102,9 +102,11 @@ class BinaryWriter { WABT_DISALLOW_COPY_AND_ASSIGN(BinaryWriter); public: - BinaryWriter(Stream*, const WriteBinaryOptions* options); + BinaryWriter(Stream*, + const WriteBinaryOptions* options, + const Module* module); - Result WriteModule(const Module* module); + Result WriteModule(); private: void WriteHeader(const char* name, int index); @@ -126,19 +128,12 @@ class BinaryWriter { const char* desc, RelocType reloc_type); template <typename T> - void WriteLoadStoreExpr(const Module* module, - const Func* func, - const Expr* expr, - const char* desc); - void WriteExpr(const Module* module, const Func* func, const Expr* expr); - void WriteExprList(const Module* module, - const Func* func, - const ExprList& exprs); - void WriteInitExpr(const Module* module, const ExprList& expr); - void WriteFuncLocals(const Module* module, - const Func* func, - const TypeVector& local_types); - void WriteFunc(const Module* module, const Func* func); + void WriteLoadStoreExpr(const Func* func, const Expr* expr, const char* desc); + void WriteExpr(const Func* func, const Expr* expr); + void WriteExprList(const Func* func, const ExprList& exprs); + void WriteInitExpr(const ExprList& expr); + void WriteFuncLocals(const Func* func, const TypeVector& local_types); + void WriteFunc(const Func* func); void WriteTable(const Table* table); void WriteMemory(const Memory* memory); void WriteGlobalHeader(const Global* global); @@ -147,7 +142,8 @@ class BinaryWriter { void WriteEmptyLinkingSection(); Stream* stream_; - const WriteBinaryOptions* options_ = nullptr; + const WriteBinaryOptions* options_; + const Module* module_; std::vector<RelocSection> reloc_sections_; RelocSection* current_reloc_section_ = nullptr; @@ -171,8 +167,10 @@ static uint8_t log2_u32(uint32_t x) { return result; } -BinaryWriter::BinaryWriter(Stream* stream, const WriteBinaryOptions* options) - : stream_(stream), options_(options) {} +BinaryWriter::BinaryWriter(Stream* stream, + const WriteBinaryOptions* options, + const Module* module) + : stream_(stream), options_(options), module_(module) {} void BinaryWriter::WriteHeader(const char* name, int index) { if (stream_->has_log_stream()) { @@ -330,8 +328,7 @@ Index BinaryWriter::GetLocalIndex(const Func* func, const Var& var) { // TODO(binji): Rename this, it is used for more than loads/stores now. template <typename T> -void BinaryWriter::WriteLoadStoreExpr(const Module* module, - const Func* func, +void BinaryWriter::WriteLoadStoreExpr(const Func* func, const Expr* expr, const char* desc) { auto* typed_expr = cast<T>(expr); @@ -341,28 +338,25 @@ void BinaryWriter::WriteLoadStoreExpr(const Module* module, WriteU32Leb128(stream_, typed_expr->offset, desc); } -void BinaryWriter::WriteExpr(const Module* module, - const Func* func, - const Expr* expr) { +void BinaryWriter::WriteExpr(const Func* func, const Expr* expr) { switch (expr->type()) { case ExprType::AtomicLoad: - WriteLoadStoreExpr<AtomicLoadExpr>(module, func, expr, "memory offset"); + WriteLoadStoreExpr<AtomicLoadExpr>(func, expr, "memory offset"); break; case ExprType::AtomicRmw: - WriteLoadStoreExpr<AtomicRmwExpr>(module, func, expr, "memory offset"); + WriteLoadStoreExpr<AtomicRmwExpr>(func, expr, "memory offset"); break; case ExprType::AtomicRmwCmpxchg: - WriteLoadStoreExpr<AtomicRmwCmpxchgExpr>(module, func, expr, - "memory offset"); + WriteLoadStoreExpr<AtomicRmwCmpxchgExpr>(func, expr, "memory offset"); break; case ExprType::AtomicStore: - WriteLoadStoreExpr<AtomicStoreExpr>(module, func, expr, "memory offset"); + WriteLoadStoreExpr<AtomicStoreExpr>(func, expr, "memory offset"); break; case ExprType::AtomicWait: - WriteLoadStoreExpr<AtomicWaitExpr>(module, func, expr, "memory offset"); + WriteLoadStoreExpr<AtomicWaitExpr>(func, expr, "memory offset"); break; case ExprType::AtomicWake: - WriteLoadStoreExpr<AtomicWakeExpr>(module, func, expr, "memory offset"); + WriteLoadStoreExpr<AtomicWakeExpr>(func, expr, "memory offset"); break; case ExprType::Binary: WriteOpcode(stream_, cast<BinaryExpr>(expr)->opcode); @@ -370,7 +364,7 @@ void BinaryWriter::WriteExpr(const Module* module, case ExprType::Block: WriteOpcode(stream_, Opcode::Block); write_inline_signature_type(stream_, cast<BlockExpr>(expr)->block.sig); - WriteExprList(module, func, cast<BlockExpr>(expr)->block.exprs); + WriteExprList(func, cast<BlockExpr>(expr)->block.exprs); WriteOpcode(stream_, Opcode::End); break; case ExprType::Br: @@ -397,14 +391,14 @@ void BinaryWriter::WriteExpr(const Module* module, break; } case ExprType::Call: { - Index index = module->GetFuncIndex(cast<CallExpr>(expr)->var); + Index index = module_->GetFuncIndex(cast<CallExpr>(expr)->var); WriteOpcode(stream_, Opcode::Call); WriteU32Leb128WithReloc(index, "function index", RelocType::FuncIndexLEB); break; } case ExprType::CallIndirect: { Index index = - module->GetFuncTypeIndex(cast<CallIndirectExpr>(expr)->decl); + module_->GetFuncTypeIndex(cast<CallIndirectExpr>(expr)->decl); WriteOpcode(stream_, Opcode::CallIndirect); WriteU32Leb128WithReloc(index, "signature index", RelocType::TypeIndexLEB); @@ -454,7 +448,7 @@ void BinaryWriter::WriteExpr(const Module* module, WriteOpcode(stream_, Opcode::Drop); break; case ExprType::GetGlobal: { - Index index = module->GetGlobalIndex(cast<GetGlobalExpr>(expr)->var); + Index index = module_->GetGlobalIndex(cast<GetGlobalExpr>(expr)->var); WriteOpcode(stream_, Opcode::GetGlobal); WriteU32Leb128WithReloc(index, "global index", RelocType::GlobalIndexLEB); break; @@ -473,10 +467,10 @@ void BinaryWriter::WriteExpr(const Module* module, auto* if_expr = cast<IfExpr>(expr); WriteOpcode(stream_, Opcode::If); write_inline_signature_type(stream_, if_expr->true_.sig); - WriteExprList(module, func, if_expr->true_.exprs); + WriteExprList(func, if_expr->true_.exprs); if (!if_expr->false_.empty()) { WriteOpcode(stream_, Opcode::Else); - WriteExprList(module, func, if_expr->false_); + WriteExprList(func, if_expr->false_); } WriteOpcode(stream_, Opcode::End); break; @@ -485,23 +479,23 @@ void BinaryWriter::WriteExpr(const Module* module, auto* if_except_expr = cast<IfExceptExpr>(expr); WriteOpcode(stream_, Opcode::IfExcept); write_inline_signature_type(stream_, if_except_expr->true_.sig); - Index index = module->GetExceptIndex(if_except_expr->except_var); + Index index = module_->GetExceptIndex(if_except_expr->except_var); WriteU32Leb128(stream_, index, "exception index"); - WriteExprList(module, func, if_except_expr->true_.exprs); + WriteExprList(func, if_except_expr->true_.exprs); if (!if_except_expr->false_.empty()) { WriteOpcode(stream_, Opcode::Else); - WriteExprList(module, func, if_except_expr->false_); + WriteExprList(func, if_except_expr->false_); } WriteOpcode(stream_, Opcode::End); break; } case ExprType::Load: - WriteLoadStoreExpr<LoadExpr>(module, func, expr, "load offset"); + WriteLoadStoreExpr<LoadExpr>(func, expr, "load offset"); break; case ExprType::Loop: WriteOpcode(stream_, Opcode::Loop); write_inline_signature_type(stream_, cast<LoopExpr>(expr)->block.sig); - WriteExprList(module, func, cast<LoopExpr>(expr)->block.exprs); + WriteExprList(func, cast<LoopExpr>(expr)->block.exprs); WriteOpcode(stream_, Opcode::End); break; case ExprType::Nop: @@ -517,7 +511,7 @@ void BinaryWriter::WriteExpr(const Module* module, WriteOpcode(stream_, Opcode::Select); break; case ExprType::SetGlobal: { - Index index = module->GetGlobalIndex(cast<SetGlobalExpr>(expr)->var); + Index index = module_->GetGlobalIndex(cast<SetGlobalExpr>(expr)->var); WriteOpcode(stream_, Opcode::SetGlobal); WriteU32Leb128WithReloc(index, "global index", RelocType::GlobalIndexLEB); break; @@ -529,7 +523,7 @@ void BinaryWriter::WriteExpr(const Module* module, break; } case ExprType::Store: - WriteLoadStoreExpr<StoreExpr>(module, func, expr, "store offset"); + WriteLoadStoreExpr<StoreExpr>(func, expr, "store offset"); break; case ExprType::TeeLocal: { Index index = GetLocalIndex(func, cast<TeeLocalExpr>(expr)->var); @@ -546,9 +540,9 @@ void BinaryWriter::WriteExpr(const Module* module, auto* try_expr = cast<TryExpr>(expr); WriteOpcode(stream_, Opcode::Try); write_inline_signature_type(stream_, try_expr->block.sig); - WriteExprList(module, func, try_expr->block.exprs); + WriteExprList(func, try_expr->block.exprs); WriteOpcode(stream_, Opcode::Catch); - WriteExprList(module, func, try_expr->catch_); + WriteExprList(func, try_expr->catch_); WriteOpcode(stream_, Opcode::End); break; } @@ -564,20 +558,17 @@ void BinaryWriter::WriteExpr(const Module* module, } } -void BinaryWriter::WriteExprList(const Module* module, - const Func* func, - const ExprList& exprs) { +void BinaryWriter::WriteExprList(const Func* func, const ExprList& exprs) { for (const Expr& expr : exprs) - WriteExpr(module, func, &expr); + WriteExpr(func, &expr); } -void BinaryWriter::WriteInitExpr(const Module* module, const ExprList& expr) { - WriteExprList(module, nullptr, expr); +void BinaryWriter::WriteInitExpr(const ExprList& expr) { + WriteExprList(nullptr, expr); WriteOpcode(stream_, Opcode::End); } -void BinaryWriter::WriteFuncLocals(const Module* module, - const Func* func, +void BinaryWriter::WriteFuncLocals(const Func* func, const TypeVector& local_types) { if (local_types.size() == 0) { WriteU32Leb128(stream_, 0, "local decl count"); @@ -619,9 +610,9 @@ void BinaryWriter::WriteFuncLocals(const Module* module, } } -void BinaryWriter::WriteFunc(const Module* module, const Func* func) { - WriteFuncLocals(module, func, func->local_types); - WriteExprList(module, func, func->exprs); +void BinaryWriter::WriteFunc(const Func* func) { + WriteFuncLocals(func, func->local_types); + WriteExprList(func, func->exprs); WriteOpcode(stream_, Opcode::End); } @@ -680,15 +671,15 @@ void BinaryWriter::WriteEmptyLinkingSection() { EndSection(); } -Result BinaryWriter::WriteModule(const Module* module) { +Result BinaryWriter::WriteModule() { stream_->WriteU32(WABT_BINARY_MAGIC, "WASM_BINARY_MAGIC"); stream_->WriteU32(WABT_BINARY_VERSION, "WASM_BINARY_VERSION"); - if (module->func_types.size()) { + if (module_->func_types.size()) { BeginKnownSection(BinarySection::Type); - WriteU32Leb128(stream_, module->func_types.size(), "num types"); - for (size_t i = 0; i < module->func_types.size(); ++i) { - const FuncType* func_type = module->func_types[i]; + WriteU32Leb128(stream_, module_->func_types.size(), "num types"); + for (size_t i = 0; i < module_->func_types.size(); ++i) { + const FuncType* func_type = module_->func_types[i]; const FuncSignature* sig = &func_type->sig; WriteHeader("type", i); WriteType(stream_, Type::Func); @@ -706,12 +697,12 @@ Result BinaryWriter::WriteModule(const Module* module) { EndSection(); } - if (module->imports.size()) { + if (module_->imports.size()) { BeginKnownSection(BinarySection::Import); - WriteU32Leb128(stream_, module->imports.size(), "num imports"); + WriteU32Leb128(stream_, module_->imports.size(), "num imports"); - for (size_t i = 0; i < module->imports.size(); ++i) { - const Import* import = module->imports[i]; + for (size_t i = 0; i < module_->imports.size(); ++i) { + const Import* import = module_->imports[i]; WriteHeader("import header", i); WriteStr(stream_, import->module_name, "import module name", PrintChars::Yes); @@ -720,9 +711,10 @@ Result BinaryWriter::WriteModule(const Module* module) { stream_->WriteU8Enum(import->kind(), "import kind"); switch (import->kind()) { case ExternalKind::Func: - WriteU32Leb128(stream_, module->GetFuncTypeIndex( - cast<FuncImport>(import)->func.decl), - "import signature index"); + WriteU32Leb128( + stream_, + module_->GetFuncTypeIndex(cast<FuncImport>(import)->func.decl), + "import signature index"); break; case ExternalKind::Table: @@ -745,92 +737,92 @@ Result BinaryWriter::WriteModule(const Module* module) { EndSection(); } - assert(module->funcs.size() >= module->num_func_imports); - Index num_funcs = module->funcs.size() - module->num_func_imports; + assert(module_->funcs.size() >= module_->num_func_imports); + Index num_funcs = module_->funcs.size() - module_->num_func_imports; if (num_funcs) { BeginKnownSection(BinarySection::Function); WriteU32Leb128(stream_, num_funcs, "num functions"); for (size_t i = 0; i < num_funcs; ++i) { - const Func* func = module->funcs[i + module->num_func_imports]; + const Func* func = module_->funcs[i + module_->num_func_imports]; char desc[100]; wabt_snprintf(desc, sizeof(desc), "function %" PRIzd " signature index", i); - WriteU32Leb128(stream_, module->GetFuncTypeIndex(func->decl), desc); + WriteU32Leb128(stream_, module_->GetFuncTypeIndex(func->decl), desc); } EndSection(); } - assert(module->tables.size() >= module->num_table_imports); - Index num_tables = module->tables.size() - module->num_table_imports; + assert(module_->tables.size() >= module_->num_table_imports); + Index num_tables = module_->tables.size() - module_->num_table_imports; if (num_tables) { BeginKnownSection(BinarySection::Table); WriteU32Leb128(stream_, num_tables, "num tables"); for (size_t i = 0; i < num_tables; ++i) { - const Table* table = module->tables[i + module->num_table_imports]; + const Table* table = module_->tables[i + module_->num_table_imports]; WriteHeader("table", i); WriteTable(table); } EndSection(); } - assert(module->memories.size() >= module->num_memory_imports); - Index num_memories = module->memories.size() - module->num_memory_imports; + assert(module_->memories.size() >= module_->num_memory_imports); + Index num_memories = module_->memories.size() - module_->num_memory_imports; if (num_memories) { BeginKnownSection(BinarySection::Memory); WriteU32Leb128(stream_, num_memories, "num memories"); for (size_t i = 0; i < num_memories; ++i) { - const Memory* memory = module->memories[i + module->num_memory_imports]; + const Memory* memory = module_->memories[i + module_->num_memory_imports]; WriteHeader("memory", i); WriteMemory(memory); } EndSection(); } - assert(module->globals.size() >= module->num_global_imports); - Index num_globals = module->globals.size() - module->num_global_imports; + assert(module_->globals.size() >= module_->num_global_imports); + Index num_globals = module_->globals.size() - module_->num_global_imports; if (num_globals) { BeginKnownSection(BinarySection::Global); WriteU32Leb128(stream_, num_globals, "num globals"); for (size_t i = 0; i < num_globals; ++i) { - const Global* global = module->globals[i + module->num_global_imports]; + const Global* global = module_->globals[i + module_->num_global_imports]; WriteGlobalHeader(global); - WriteInitExpr(module, global->init_expr); + WriteInitExpr(global->init_expr); } EndSection(); } - if (module->exports.size()) { + if (module_->exports.size()) { BeginKnownSection(BinarySection::Export); - WriteU32Leb128(stream_, module->exports.size(), "num exports"); + WriteU32Leb128(stream_, module_->exports.size(), "num exports"); - for (const Export* export_ : module->exports) { + for (const Export* export_ : module_->exports) { WriteStr(stream_, export_->name, "export name", PrintChars::Yes); stream_->WriteU8Enum(export_->kind, "export kind"); switch (export_->kind) { case ExternalKind::Func: { - Index index = module->GetFuncIndex(export_->var); + Index index = module_->GetFuncIndex(export_->var); WriteU32Leb128(stream_, index, "export func index"); break; } case ExternalKind::Table: { - Index index = module->GetTableIndex(export_->var); + Index index = module_->GetTableIndex(export_->var); WriteU32Leb128(stream_, index, "export table index"); break; } case ExternalKind::Memory: { - Index index = module->GetMemoryIndex(export_->var); + Index index = module_->GetMemoryIndex(export_->var); WriteU32Leb128(stream_, index, "export memory index"); break; } case ExternalKind::Global: { - Index index = module->GetGlobalIndex(export_->var); + Index index = module_->GetGlobalIndex(export_->var); WriteU32Leb128(stream_, index, "export global index"); break; } case ExternalKind::Except: { - Index index = module->GetExceptIndex(export_->var); + Index index = module_->GetExceptIndex(export_->var); WriteU32Leb128(stream_, index, "export exception index"); break; } @@ -839,8 +831,8 @@ Result BinaryWriter::WriteModule(const Module* module) { EndSection(); } - if (module->starts.size()) { - Index start_func_index = module->GetFuncIndex(*module->starts[0]); + if (module_->starts.size()) { + Index start_func_index = module_->GetFuncIndex(*module_->starts[0]); if (start_func_index != kInvalidIndex) { BeginKnownSection(BinarySection::Start); WriteU32Leb128(stream_, start_func_index, "start func index"); @@ -848,18 +840,18 @@ Result BinaryWriter::WriteModule(const Module* module) { } } - if (module->elem_segments.size()) { + if (module_->elem_segments.size()) { BeginKnownSection(BinarySection::Elem); - WriteU32Leb128(stream_, module->elem_segments.size(), "num elem segments"); - for (size_t i = 0; i < module->elem_segments.size(); ++i) { - ElemSegment* segment = module->elem_segments[i]; - Index table_index = module->GetTableIndex(segment->table_var); + WriteU32Leb128(stream_, module_->elem_segments.size(), "num elem segments"); + for (size_t i = 0; i < module_->elem_segments.size(); ++i) { + ElemSegment* segment = module_->elem_segments[i]; + Index table_index = module_->GetTableIndex(segment->table_var); WriteHeader("elem segment header", i); WriteU32Leb128(stream_, table_index, "table index"); - WriteInitExpr(module, segment->offset); + WriteInitExpr(segment->offset); WriteU32Leb128(stream_, segment->vars.size(), "num function indices"); for (const Var& var : segment->vars) { - Index index = module->GetFuncIndex(var); + Index index = module_->GetFuncIndex(var); WriteU32Leb128WithReloc(index, "function index", RelocType::FuncIndexLEB); } @@ -867,13 +859,13 @@ Result BinaryWriter::WriteModule(const Module* module) { EndSection(); } - assert(module->excepts.size() >= module->num_except_imports); - Index num_exceptions = module->excepts.size() - module->num_except_imports; + assert(module_->excepts.size() >= module_->num_except_imports); + Index num_exceptions = module_->excepts.size() - module_->num_except_imports; if (num_exceptions) { BeginCustomSection("exception"); WriteU32Leb128(stream_, num_exceptions, "exception count"); - for (Index i = module->num_except_imports; i < num_exceptions; ++i) { - WriteExceptType(&module->excepts[i]->sig); + for (Index i = module_->num_except_imports; i < num_exceptions; ++i) { + WriteExceptType(&module_->excepts[i]->sig); } EndSection(); } @@ -884,28 +876,28 @@ Result BinaryWriter::WriteModule(const Module* module) { for (size_t i = 0; i < num_funcs; ++i) { WriteHeader("function body", i); - const Func* func = module->funcs[i + module->num_func_imports]; + const Func* func = module_->funcs[i + module_->num_func_imports]; /* TODO(binji): better guess of the size of the function body section */ const Offset leb_size_guess = 1; Offset body_size_offset = WriteU32Leb128Space(leb_size_guess, "func body size (guess)"); - WriteFunc(module, func); + WriteFunc(func); WriteFixupU32Leb128Size(body_size_offset, leb_size_guess, "FIXUP func body size"); } EndSection(); } - if (module->data_segments.size()) { + if (module_->data_segments.size()) { BeginKnownSection(BinarySection::Data); - WriteU32Leb128(stream_, module->data_segments.size(), "num data segments"); - for (size_t i = 0; i < module->data_segments.size(); ++i) { - const DataSegment* segment = module->data_segments[i]; + WriteU32Leb128(stream_, module_->data_segments.size(), "num data segments"); + for (size_t i = 0; i < module_->data_segments.size(); ++i) { + const DataSegment* segment = module_->data_segments[i]; WriteHeader("data segment header", i); - Index memory_index = module->GetMemoryIndex(segment->memory_var); + Index memory_index = module_->GetMemoryIndex(segment->memory_var); WriteU32Leb128(stream_, memory_index, "memory index"); - WriteInitExpr(module, segment->offset); + WriteInitExpr(segment->offset); WriteU32Leb128(stream_, segment->data.size(), "data segment size"); WriteHeader("data segment data", i); stream_->WriteData(segment->data, "data segment data"); @@ -920,7 +912,7 @@ Result BinaryWriter::WriteModule(const Module* module) { BeginCustomSection(WABT_BINARY_SECTION_NAME); size_t named_functions = 0; - for (const Func* func : module->funcs) { + for (const Func* func : module_->funcs) { if (!func->name.empty()) { named_functions++; } @@ -931,8 +923,8 @@ Result BinaryWriter::WriteModule(const Module* module) { BeginSubsection("function name subsection"); WriteU32Leb128(stream_, named_functions, "num functions"); - for (size_t i = 0; i < module->funcs.size(); ++i) { - const Func* func = module->funcs[i]; + for (size_t i = 0; i < module_->funcs.size(); ++i) { + const Func* func = module_->funcs[i]; if (func->name.empty()) { continue; } @@ -946,9 +938,9 @@ Result BinaryWriter::WriteModule(const Module* module) { WriteU32Leb128(stream_, 2, "local name type"); BeginSubsection("local name subsection"); - WriteU32Leb128(stream_, module->funcs.size(), "num functions"); - for (size_t i = 0; i < module->funcs.size(); ++i) { - const Func* func = module->funcs[i]; + WriteU32Leb128(stream_, module_->funcs.size(), "num functions"); + for (size_t i = 0; i < module_->funcs.size(); ++i) { + const Func* func = module_->funcs[i]; Index num_params = func->GetNumParams(); Index num_locals = func->local_types.size(); Index num_params_and_locals = func->GetNumParamsAndLocals(); @@ -993,8 +985,8 @@ Result BinaryWriter::WriteModule(const Module* module) { Result WriteBinaryModule(Stream* stream, const Module* module, const WriteBinaryOptions* options) { - BinaryWriter binary_writer(stream, options); - return binary_writer.WriteModule(module); + BinaryWriter binary_writer(stream, options, module); + return binary_writer.WriteModule(); } } // namespace wabt |