diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/apply-names.cc | 11 | ||||
-rw-r--r-- | src/binary-reader-ir.cc | 422 | ||||
-rw-r--r-- | src/binary-reader-linker.cc | 2 | ||||
-rw-r--r-- | src/binary-writer-spec.cc | 170 | ||||
-rw-r--r-- | src/binary-writer.cc | 49 | ||||
-rw-r--r-- | src/common.h | 19 | ||||
-rw-r--r-- | src/expr-visitor.cc | 16 | ||||
-rw-r--r-- | src/generate-names.cc | 6 | ||||
-rw-r--r-- | src/interpreter.h | 4 | ||||
-rw-r--r-- | src/ir.cc | 228 | ||||
-rw-r--r-- | src/ir.h | 455 | ||||
-rw-r--r-- | src/resolve-names.cc | 23 | ||||
-rw-r--r-- | src/tools/wasm-link.cc | 3 | ||||
-rw-r--r-- | src/validator.cc | 146 | ||||
-rw-r--r-- | src/wasm-link.h | 2 | ||||
-rw-r--r-- | src/wast-parser.cc | 589 | ||||
-rw-r--r-- | src/wast-parser.h | 2 | ||||
-rw-r--r-- | src/wat-writer.cc | 370 |
18 files changed, 1238 insertions, 1279 deletions
diff --git a/src/apply-names.cc b/src/apply-names.cc index 1616ea2d..a83d34d3 100644 --- a/src/apply-names.cc +++ b/src/apply-names.cc @@ -202,7 +202,7 @@ Result NameApplier::UseNameForParamAndLocalVar(Func* func, Var* var) { } Result NameApplier::BeginBlockExpr(BlockExpr* expr) { - PushLabel(expr->block->label); + PushLabel(expr->block.label); return Result::Ok; } @@ -212,7 +212,7 @@ Result NameApplier::EndBlockExpr(BlockExpr* expr) { } Result NameApplier::BeginLoopExpr(LoopExpr* expr) { - PushLabel(expr->block->label); + PushLabel(expr->block.label); return Result::Ok; } @@ -234,8 +234,7 @@ Result NameApplier::OnBrIfExpr(BrIfExpr* expr) { } Result NameApplier::OnBrTableExpr(BrTableExpr* expr) { - VarVector& targets = *expr->targets; - for (Var& target : targets) { + for (Var& target : expr->targets) { string_view label = FindLabelByVar(&target); UseNameForVar(label, &target); } @@ -246,7 +245,7 @@ Result NameApplier::OnBrTableExpr(BrTableExpr* expr) { } Result NameApplier::BeginTryExpr(TryExpr* expr) { - PushLabel(expr->block->label); + PushLabel(expr->block.label); return Result::Ok; } @@ -294,7 +293,7 @@ Result NameApplier::OnGetLocalExpr(GetLocalExpr* expr) { } Result NameApplier::BeginIfExpr(IfExpr* expr) { - PushLabel(expr->true_->label); + PushLabel(expr->true_.label); return Result::Ok; } diff --git a/src/binary-reader-ir.cc b/src/binary-reader-ir.cc index 96e228f1..8b105981 100644 --- a/src/binary-reader-ir.cc +++ b/src/binary-reader-ir.cc @@ -40,16 +40,15 @@ namespace wabt { namespace { struct LabelNode { - LabelNode(LabelType, ExprList* exprs); + LabelNode(LabelType, ExprList* exprs, Expr* context = nullptr); LabelType label_type; ExprList* exprs; Expr* context; }; -LabelNode::LabelNode(LabelType label_type, ExprList* exprs) - : label_type(label_type), exprs(exprs), context(nullptr) {} - +LabelNode::LabelNode(LabelType label_type, ExprList* exprs, Expr* context) + : label_type(label_type), exprs(exprs), context(context) {} class BinaryReaderIR : public BinaryReaderNop { public: @@ -67,9 +66,6 @@ class BinaryReaderIR : public BinaryReaderNop { Type* result_types) override; Result OnImportCount(Index count) override; - Result OnImport(Index index, - string_view module_name, - string_view field_name) override; Result OnImportFunc(Index import_index, string_view module_name, string_view field_name, @@ -175,10 +171,8 @@ class BinaryReaderIR : public BinaryReaderNop { Result BeginElemSegment(Index index, Index table_index) override; Result BeginElemSegmentInitExpr(Index index) override; Result EndElemSegmentInitExpr(Index index) override; - Result OnElemSegmentFunctionIndexCount(Index index, - Index count) override; - Result OnElemSegmentFunctionIndex(Index index, - Index func_index) override; + Result OnElemSegmentFunctionIndexCount(Index index, Index count) override; + Result OnElemSegmentFunctionIndex(Index index, Index func_index) override; Result OnDataSegmentCount(Index count) override; Result BeginDataSegment(Index index, Index memory_index) override; @@ -191,8 +185,7 @@ class BinaryReaderIR : public BinaryReaderNop { Result OnFunctionNamesCount(Index num_functions) override; Result OnFunctionName(Index function_index, string_view function_name) override; - Result OnLocalNameLocalCount(Index function_index, - Index num_locals) override; + Result OnLocalNameLocalCount(Index function_index, Index num_locals) override; Result OnLocalName(Index function_index, Index local_index, string_view local_name) override; @@ -212,12 +205,14 @@ class BinaryReaderIR : public BinaryReaderNop { bool HandleError(Offset offset, const char* message); Location GetLocation() const; void PrintError(const char* format, ...); - void PushLabel(LabelType label_type, ExprList* first); + void PushLabel(LabelType label_type, + ExprList* first, + Expr* context = nullptr); Result PopLabel(); Result GetLabelAt(LabelNode** label, Index depth); Result TopLabel(LabelNode** label); - Result AppendExpr(Expr* expr); - Result AppendCatch(Catch* catch_); + Result AppendExpr(std::unique_ptr<Expr> expr); + Result AppendCatch(Catch&& catch_); ErrorHandler* error_handler = nullptr; Module* module = nullptr; @@ -241,13 +236,15 @@ Location BinaryReaderIR::GetLocation() const { } void WABT_PRINTF_FORMAT(2, 3) BinaryReaderIR::PrintError(const char* format, - ...) { + ...) { WABT_SNPRINTF_ALLOCA(buffer, length, format); HandleError(kInvalidOffset, buffer); } -void BinaryReaderIR::PushLabel(LabelType label_type, ExprList* first) { - label_stack.emplace_back(label_type, first); +void BinaryReaderIR::PushLabel(LabelType label_type, + ExprList* first, + Expr* context) { + label_stack.emplace_back(label_type, first, context); } Result BinaryReaderIR::PopLabel() { @@ -275,16 +272,12 @@ Result BinaryReaderIR::TopLabel(LabelNode** label) { return GetLabelAt(label, 0); } -Result BinaryReaderIR::AppendExpr(Expr* expr) { - // TODO(binji): Probably should be set in the Expr constructor instead. - expr->loc = GetLocation(); - +Result BinaryReaderIR::AppendExpr(std::unique_ptr<Expr> expr) { LabelNode* label; if (Failed(TopLabel(&label))) { - delete expr; return Result::Error; } - label->exprs->push_back(expr); + label->exprs->push_back(expr.release()); return Result::Ok; } @@ -302,15 +295,16 @@ Result BinaryReaderIR::OnTypeCount(Index count) { } Result BinaryReaderIR::OnType(Index index, - Index param_count, - Type* param_types, - Index result_count, - Type* result_types) { - auto func_type = new FuncType(); - func_type->sig.param_types.assign(param_types, param_types + param_count); - func_type->sig.result_types.assign(result_types, result_types + result_count); - module->func_types.push_back(func_type); - module->fields.push_back(new FuncTypeModuleField(func_type, GetLocation())); + Index param_count, + Type* param_types, + Index result_count, + Type* result_types) { + auto field = MakeUnique<FuncTypeModuleField>(GetLocation()); + auto&& func_type = field->func_type; + func_type.sig.param_types.assign(param_types, param_types + param_count); + func_type.sig.result_types.assign(result_types, result_types + result_count); + module->func_types.push_back(&func_type); + module->fields.push_back(field.release()); return Result::Ok; } @@ -319,32 +313,22 @@ Result BinaryReaderIR::OnImportCount(Index count) { return Result::Ok; } -Result BinaryReaderIR::OnImport(Index index, - string_view module_name, - string_view field_name) { - auto import = new Import(); - import->module_name = module_name.to_string(); - import->field_name = field_name.to_string(); - module->imports.push_back(import); - module->fields.push_back(new ImportModuleField(import, GetLocation())); - return Result::Ok; -} - Result BinaryReaderIR::OnImportFunc(Index import_index, string_view module_name, string_view field_name, Index func_index, Index sig_index) { - assert(import_index == module->imports.size() - 1); - Import* import = module->imports[import_index]; - - import->kind = ExternalKind::Func; - import->func = new Func(); - import->func->decl.has_func_type = true; - import->func->decl.type_var = Var(sig_index, GetLocation()); - import->func->decl.sig = module->func_types[sig_index]->sig; - - module->funcs.push_back(import->func); + auto import = MakeUnique<FuncImport>(); + import->module_name = module_name.to_string(); + import->field_name = field_name.to_string(); + import->func.decl.has_func_type = true; + import->func.decl.type_var = Var(sig_index, GetLocation()); + import->func.decl.sig = module->func_types[sig_index]->sig; + module->funcs.push_back(&import->func); + module->imports.push_back(import.get()); + + auto field = MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->fields.push_back(field.release()); module->num_func_imports++; return Result::Ok; } @@ -355,12 +339,15 @@ Result BinaryReaderIR::OnImportTable(Index import_index, Index table_index, Type elem_type, const Limits* elem_limits) { - assert(import_index == module->imports.size() - 1); - Import* import = module->imports[import_index]; - import->kind = ExternalKind::Table; - import->table = new Table(); - import->table->elem_limits = *elem_limits; - module->tables.push_back(import->table); + auto import = MakeUnique<TableImport>(); + import->module_name = module_name.to_string(); + import->field_name = field_name.to_string(); + import->table.elem_limits = *elem_limits; + module->tables.push_back(&import->table); + module->imports.push_back(import.get()); + + auto field = MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->fields.push_back(field.release()); module->num_table_imports++; return Result::Ok; } @@ -370,12 +357,15 @@ Result BinaryReaderIR::OnImportMemory(Index import_index, string_view field_name, Index memory_index, const Limits* page_limits) { - assert(import_index == module->imports.size() - 1); - Import* import = module->imports[import_index]; - import->kind = ExternalKind::Memory; - import->memory = new Memory(); - import->memory->page_limits = *page_limits; - module->memories.push_back(import->memory); + auto import = MakeUnique<MemoryImport>(); + import->module_name = module_name.to_string(); + import->field_name = field_name.to_string(); + import->memory.page_limits = *page_limits; + module->memories.push_back(&import->memory); + module->imports.push_back(import.get()); + + auto field = MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->fields.push_back(field.release()); module->num_memory_imports++; return Result::Ok; } @@ -386,13 +376,16 @@ Result BinaryReaderIR::OnImportGlobal(Index import_index, Index global_index, Type type, bool mutable_) { - assert(import_index == module->imports.size() - 1); - Import* import = module->imports[import_index]; - import->kind = ExternalKind::Global; - import->global = new Global(); - import->global->type = type; - import->global->mutable_ = mutable_; - module->globals.push_back(import->global); + auto import = MakeUnique<GlobalImport>(); + import->module_name = module_name.to_string(); + import->field_name = field_name.to_string(); + import->global.type = type; + import->global.mutable_ = mutable_; + module->globals.push_back(&import->global); + module->imports.push_back(import.get()); + + auto field = MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->fields.push_back(field.release()); module->num_global_imports++; return Result::Ok; } @@ -402,11 +395,15 @@ Result BinaryReaderIR::OnImportException(Index import_index, string_view field_name, Index except_index, TypeVector& sig) { - assert(import_index == module->imports.size() - 1); - Import* import = module->imports[import_index]; - import->kind = ExternalKind::Except; - import->except = new Exception(sig); - module->excepts.push_back(import->except); + auto import = MakeUnique<ExceptionImport>(); + import->module_name = module_name.to_string(); + import->field_name = field_name.to_string(); + import->except.sig = sig; + module->excepts.push_back(&import->except); + module->imports.push_back(import.get()); + + auto field = MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->fields.push_back(field.release()); return Result::Ok; } @@ -416,13 +413,14 @@ Result BinaryReaderIR::OnFunctionCount(Index count) { } Result BinaryReaderIR::OnFunction(Index index, Index sig_index) { - auto func = new Func(); - func->decl.has_func_type = true; - func->decl.type_var = Var(sig_index, GetLocation()); - func->decl.sig = module->func_types[sig_index]->sig; + auto field = MakeUnique<FuncModuleField>(GetLocation()); + auto&& func = field->func; + func.decl.has_func_type = true; + func.decl.type_var = Var(sig_index, GetLocation()); + func.decl.sig = module->func_types[sig_index]->sig; - module->funcs.push_back(func); - module->fields.push_back(new FuncModuleField(func, GetLocation())); + module->funcs.push_back(&func); + module->fields.push_back(field.release()); return Result::Ok; } @@ -434,10 +432,11 @@ Result BinaryReaderIR::OnTableCount(Index count) { Result BinaryReaderIR::OnTable(Index index, Type elem_type, const Limits* elem_limits) { - auto table = new Table(); - table->elem_limits = *elem_limits; - module->tables.push_back(table); - module->fields.push_back(new TableModuleField(table, GetLocation())); + auto field = MakeUnique<TableModuleField>(GetLocation()); + auto&& table = field->table; + table.elem_limits = *elem_limits; + module->tables.push_back(&table); + module->fields.push_back(field.release()); return Result::Ok; } @@ -447,10 +446,11 @@ Result BinaryReaderIR::OnMemoryCount(Index count) { } Result BinaryReaderIR::OnMemory(Index index, const Limits* page_limits) { - auto memory = new Memory(); - memory->page_limits = *page_limits; - module->memories.push_back(memory); - module->fields.push_back(new MemoryModuleField(memory, GetLocation())); + auto field = MakeUnique<MemoryModuleField>(GetLocation()); + auto&& memory = field->memory; + memory.page_limits = *page_limits; + module->memories.push_back(&memory); + module->fields.push_back(field.release()); return Result::Ok; } @@ -460,11 +460,12 @@ Result BinaryReaderIR::OnGlobalCount(Index count) { } Result BinaryReaderIR::BeginGlobal(Index index, Type type, bool mutable_) { - auto global = new Global(); - global->type = type; - global->mutable_ = mutable_; - module->globals.push_back(global); - module->fields.push_back(new GlobalModuleField(global, GetLocation())); + auto field = MakeUnique<GlobalModuleField>(GetLocation()); + auto&& global = field->global; + global.type = type; + global.mutable_ = mutable_; + module->globals.push_back(&global); + module->fields.push_back(field.release()); return Result::Ok; } @@ -489,8 +490,9 @@ Result BinaryReaderIR::OnExport(Index index, ExternalKind kind, Index item_index, string_view name) { - auto export_ = new Export(); - export_->name = name.to_string(); + auto field = MakeUnique<ExportModuleField>(GetLocation()); + auto&& export_ = field->export_; + export_.name = name.to_string(); switch (kind) { case ExternalKind::Func: assert(item_index < module->funcs.size()); @@ -508,10 +510,10 @@ Result BinaryReaderIR::OnExport(Index index, // Note: Can't check if index valid, exceptions section comes later. break; } - export_->var = Var(item_index, GetLocation()); - export_->kind = kind; - module->exports.push_back(export_); - module->fields.push_back(new ExportModuleField(export_, GetLocation())); + export_.var = Var(item_index, GetLocation()); + export_.kind = kind; + module->exports.push_back(&export_); + module->fields.push_back(field.release()); return Result::Ok; } @@ -542,72 +544,63 @@ Result BinaryReaderIR::OnLocalDecl(Index decl_index, Index count, Type type) { } Result BinaryReaderIR::OnBinaryExpr(Opcode opcode) { - auto expr = new BinaryExpr(opcode); - return AppendExpr(expr); + return AppendExpr(MakeUnique<BinaryExpr>(opcode, GetLocation())); } Result BinaryReaderIR::OnBlockExpr(Index num_types, Type* sig_types) { - auto expr = new BlockExpr(new Block()); - expr->block->sig.assign(sig_types, sig_types + num_types); - if (Failed(AppendExpr(expr))) - return Result::Error; - PushLabel(LabelType::Block, &expr->block->exprs); + auto expr = MakeUnique<BlockExpr>(GetLocation()); + expr->block.sig.assign(sig_types, sig_types + num_types); + auto* expr_list = &expr->block.exprs; + CHECK_RESULT(AppendExpr(std::move(expr))); + PushLabel(LabelType::Block, expr_list); return Result::Ok; } Result BinaryReaderIR::OnBrExpr(Index depth) { - auto expr = new BrExpr(Var(depth, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<BrExpr>(Var(depth, GetLocation()))); } Result BinaryReaderIR::OnBrIfExpr(Index depth) { - auto expr = new BrIfExpr(Var(depth, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<BrIfExpr>(Var(depth, GetLocation()))); } Result BinaryReaderIR::OnBrTableExpr(Index num_targets, Index* target_depths, Index default_target_depth) { - VarVector* targets = new VarVector(); - targets->resize(num_targets); + auto expr = MakeUnique<BrTableExpr>(GetLocation()); + expr->default_target = Var(default_target_depth); + expr->targets.resize(num_targets); for (Index i = 0; i < num_targets; ++i) { - (*targets)[i] = Var(target_depths[i]); + expr->targets[i] = Var(target_depths[i]); } - auto expr = new BrTableExpr(targets, - Var(default_target_depth, GetLocation())); - return AppendExpr(expr); + return AppendExpr(std::move(expr)); } Result BinaryReaderIR::OnCallExpr(Index func_index) { assert(func_index < module->funcs.size()); - auto expr = new CallExpr(Var(func_index, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<CallExpr>(Var(func_index, GetLocation()))); } Result BinaryReaderIR::OnCallIndirectExpr(Index sig_index) { assert(sig_index < module->func_types.size()); - auto expr = new CallIndirectExpr(Var(sig_index, GetLocation())); - return AppendExpr(expr); + return AppendExpr( + MakeUnique<CallIndirectExpr>(Var(sig_index, GetLocation()))); } Result BinaryReaderIR::OnCompareExpr(Opcode opcode) { - auto expr = new CompareExpr(opcode); - return AppendExpr(expr); + return AppendExpr(MakeUnique<CompareExpr>(opcode, GetLocation())); } Result BinaryReaderIR::OnConvertExpr(Opcode opcode) { - auto expr = new ConvertExpr(opcode); - return AppendExpr(expr); + return AppendExpr(MakeUnique<ConvertExpr>(opcode, GetLocation())); } Result BinaryReaderIR::OnCurrentMemoryExpr() { - auto expr = new CurrentMemoryExpr(); - return AppendExpr(expr); + return AppendExpr(MakeUnique<CurrentMemoryExpr>(GetLocation())); } Result BinaryReaderIR::OnDropExpr() { - auto expr = new DropExpr(); - return AppendExpr(expr); + return AppendExpr(MakeUnique<DropExpr>(GetLocation())); } Result BinaryReaderIR::OnElseExpr() { @@ -631,162 +624,139 @@ Result BinaryReaderIR::OnEndExpr() { } Result BinaryReaderIR::OnF32ConstExpr(uint32_t value_bits) { - auto expr = new ConstExpr(Const(Const::F32(), value_bits, GetLocation())); - return AppendExpr(expr); + return AppendExpr( + MakeUnique<ConstExpr>(Const::F32(value_bits, GetLocation()))); } Result BinaryReaderIR::OnF64ConstExpr(uint64_t value_bits) { - auto expr = new ConstExpr(Const(Const::F64(), value_bits, GetLocation())); - return AppendExpr(expr); + return AppendExpr( + MakeUnique<ConstExpr>(Const::F64(value_bits, GetLocation()))); } Result BinaryReaderIR::OnGetGlobalExpr(Index global_index) { - auto expr = new GetGlobalExpr(Var(global_index, GetLocation())); - return AppendExpr(expr); + return AppendExpr( + MakeUnique<GetGlobalExpr>(Var(global_index, GetLocation()))); } Result BinaryReaderIR::OnGetLocalExpr(Index local_index) { - auto expr = new GetLocalExpr(Var(local_index, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<GetLocalExpr>(Var(local_index, GetLocation()))); } Result BinaryReaderIR::OnGrowMemoryExpr() { - auto expr = new GrowMemoryExpr(); - return AppendExpr(expr); + return AppendExpr(MakeUnique<GrowMemoryExpr>()); } Result BinaryReaderIR::OnI32ConstExpr(uint32_t value) { - auto expr = new ConstExpr(Const(Const::I32(), value, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<ConstExpr>(Const::I32(value, GetLocation()))); } Result BinaryReaderIR::OnI64ConstExpr(uint64_t value) { - auto expr = new ConstExpr(Const(Const::I64(), value, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<ConstExpr>(Const::I64(value, GetLocation()))); } Result BinaryReaderIR::OnIfExpr(Index num_types, Type* sig_types) { - auto expr = new IfExpr(new Block()); - expr->true_->sig.assign(sig_types, sig_types + num_types); - if (Failed(AppendExpr(expr))) - return Result::Error; - PushLabel(LabelType::If, &expr->true_->exprs); + auto expr = MakeUnique<IfExpr>(GetLocation()); + expr->true_.sig.assign(sig_types, sig_types + num_types); + auto* expr_list = &expr->true_.exprs; + CHECK_RESULT(AppendExpr(std::move(expr))); + PushLabel(LabelType::If, expr_list); return Result::Ok; } Result BinaryReaderIR::OnLoadExpr(Opcode opcode, uint32_t alignment_log2, Address offset) { - auto expr = new LoadExpr(opcode, 1 << alignment_log2, offset); - return AppendExpr(expr); + return AppendExpr(MakeUnique<LoadExpr>(opcode, 1 << alignment_log2, offset)); } Result BinaryReaderIR::OnLoopExpr(Index num_types, Type* sig_types) { - auto expr = new LoopExpr(new Block()); - expr->block->sig.assign(sig_types, sig_types + num_types); - if (Failed(AppendExpr(expr))) - return Result::Error; - PushLabel(LabelType::Loop, &expr->block->exprs); + auto expr = MakeUnique<LoopExpr>(); + expr->block.sig.assign(sig_types, sig_types + num_types); + auto* expr_list = &expr->block.exprs; + CHECK_RESULT(AppendExpr(std::move(expr))); + PushLabel(LabelType::Loop, expr_list); return Result::Ok; } Result BinaryReaderIR::OnNopExpr() { - auto expr = new NopExpr(); - return AppendExpr(expr); + return AppendExpr(MakeUnique<NopExpr>(GetLocation())); } Result BinaryReaderIR::OnRethrowExpr(Index depth) { - return AppendExpr(new RethrowExpr(Var(depth, GetLocation()))); + return AppendExpr(MakeUnique<RethrowExpr>(Var(depth, GetLocation()))); } Result BinaryReaderIR::OnReturnExpr() { - auto expr = new ReturnExpr(); - return AppendExpr(expr); + return AppendExpr(MakeUnique<ReturnExpr>()); } Result BinaryReaderIR::OnSelectExpr() { - auto expr = new SelectExpr(); - return AppendExpr(expr); + return AppendExpr(MakeUnique<SelectExpr>()); } Result BinaryReaderIR::OnSetGlobalExpr(Index global_index) { - auto expr = new SetGlobalExpr(Var(global_index, GetLocation())); - return AppendExpr(expr); + return AppendExpr( + MakeUnique<SetGlobalExpr>(Var(global_index, GetLocation()))); } Result BinaryReaderIR::OnSetLocalExpr(Index local_index) { - auto expr = new SetLocalExpr(Var(local_index, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<SetLocalExpr>(Var(local_index, GetLocation()))); } Result BinaryReaderIR::OnStoreExpr(Opcode opcode, uint32_t alignment_log2, Address offset) { - auto expr = new StoreExpr(opcode, 1 << alignment_log2, offset); - return AppendExpr(expr); + return AppendExpr(MakeUnique<StoreExpr>(opcode, 1 << alignment_log2, offset)); } Result BinaryReaderIR::OnThrowExpr(Index except_index) { - return AppendExpr(new ThrowExpr(Var(except_index, GetLocation()))); + return AppendExpr(MakeUnique<ThrowExpr>(Var(except_index, GetLocation()))); } Result BinaryReaderIR::OnTeeLocalExpr(Index local_index) { - auto expr = new TeeLocalExpr(Var(local_index, GetLocation())); - return AppendExpr(expr); + return AppendExpr(MakeUnique<TeeLocalExpr>(Var(local_index, GetLocation()))); } Result BinaryReaderIR::OnTryExpr(Index num_types, Type* sig_types) { - auto expr = new TryExpr(); - expr->block = new Block(); - expr->block->sig.assign(sig_types, sig_types + num_types); - if (Failed(AppendExpr(expr))) - return Result::Error; - PushLabel(LabelType::Try, &expr->block->exprs); - LabelNode* label = nullptr; - { Result result = TopLabel(&label); - (void) result; - assert(Succeeded(result)); - } - label->context = expr; + auto expr_ptr = MakeUnique<TryExpr>(); + // Save expr so it can be used below, after expr_ptr has been moved. + auto* expr = expr_ptr.get(); + auto* expr_list = &expr->block.exprs; + expr->block.sig.assign(sig_types, sig_types + num_types); + CHECK_RESULT(AppendExpr(std::move(expr_ptr))); + PushLabel(LabelType::Try, expr_list, expr); return Result::Ok; } -Result BinaryReaderIR::AppendCatch(Catch* catch_) { +Result BinaryReaderIR::AppendCatch(Catch&& catch_) { LabelNode* label = nullptr; - if (Succeeded(TopLabel(&label)) && label->label_type == LabelType::Try) { - if (auto try_ = dyn_cast<TryExpr>(label->context)) { - // TODO(karlschimpf) Probably should be set in the Catch constructor. - catch_->loc = GetLocation(); - try_->catches.push_back(catch_); - label->exprs = &catch_->exprs; - return Result::Ok; - } - } - if (label != nullptr) + CHECK_RESULT(TopLabel(&label)); + + if (label->label_type != LabelType::Try) { PrintError("catch not inside try block"); - delete catch_; - return Result::Error; + return Result::Error; + } + + auto try_ = cast<TryExpr>(label->context); + try_->catches.push_back(std::move(catch_)); + label->exprs = &try_->catches.back().exprs; + return Result::Ok; } Result BinaryReaderIR::OnCatchExpr(Index except_index) { - ExprList empty; - return AppendCatch(new Catch(Var(except_index, GetLocation()))); - return Result::Error; + return AppendCatch(Catch(Var(except_index, GetLocation()))); } Result BinaryReaderIR::OnCatchAllExpr() { - ExprList empty; - return AppendCatch(new Catch()); + return AppendCatch(Catch(GetLocation())); } Result BinaryReaderIR::OnUnaryExpr(Opcode opcode) { - auto expr = new UnaryExpr(opcode); - return AppendExpr(expr); + return AppendExpr(MakeUnique<UnaryExpr>(opcode)); } Result BinaryReaderIR::OnUnreachableExpr() { - auto expr = new UnreachableExpr(); - return AppendExpr(expr); + return AppendExpr(MakeUnique<UnreachableExpr>()); } Result BinaryReaderIR::EndFunctionBody(Index index) { @@ -801,10 +771,11 @@ Result BinaryReaderIR::OnElemSegmentCount(Index count) { } Result BinaryReaderIR::BeginElemSegment(Index index, Index table_index) { - auto elem_segment = new ElemSegment(); - elem_segment->table_var = Var(table_index, GetLocation()); - module->elem_segments.push_back(elem_segment); - module->fields.push_back(new ElemSegmentModuleField(elem_segment, GetLocation())); + auto field = MakeUnique<ElemSegmentModuleField>(GetLocation()); + auto&& elem_segment = field->elem_segment; + elem_segment.table_var = Var(table_index, GetLocation()); + module->elem_segments.push_back(&elem_segment); + module->fields.push_back(field.release()); return Result::Ok; } @@ -844,10 +815,11 @@ Result BinaryReaderIR::OnDataSegmentCount(Index count) { } Result BinaryReaderIR::BeginDataSegment(Index index, Index memory_index) { - auto data_segment = new DataSegment(); - data_segment->memory_var = Var(memory_index, GetLocation()); - module->data_segments.push_back(data_segment); - module->fields.push_back(new DataSegmentModuleField(data_segment, GetLocation())); + auto field = MakeUnique<DataSegmentModuleField>(GetLocation()); + auto&& data_segment = field->data_segment; + data_segment.memory_var = Var(memory_index, GetLocation()); + module->data_segments.push_back(&data_segment); + module->fields.push_back(field.release()); return Result::Ok; } @@ -914,14 +886,14 @@ Result BinaryReaderIR::OnLocalNameLocalCount(Index index, Index count) { } Result BinaryReaderIR::OnInitExprF32ConstExpr(Index index, uint32_t value) { - auto expr = new ConstExpr(Const(Const::F32(), value, GetLocation())); + auto expr = new ConstExpr(Const::F32(value, GetLocation())); expr->loc = GetLocation(); current_init_expr->push_back(expr); return Result::Ok; } Result BinaryReaderIR::OnInitExprF64ConstExpr(Index index, uint64_t value) { - auto expr = new ConstExpr(Const(Const::F64(), value, GetLocation())); + auto expr = new ConstExpr(Const::F64(value, GetLocation())); expr->loc = GetLocation(); current_init_expr->push_back(expr); return Result::Ok; @@ -936,14 +908,14 @@ Result BinaryReaderIR::OnInitExprGetGlobalExpr(Index index, } Result BinaryReaderIR::OnInitExprI32ConstExpr(Index index, uint32_t value) { - auto expr = new ConstExpr(Const(Const::I32(), value, GetLocation())); + auto expr = new ConstExpr(Const::I32(value, GetLocation())); expr->loc = GetLocation(); current_init_expr->push_back(expr); return Result::Ok; } Result BinaryReaderIR::OnInitExprI64ConstExpr(Index index, uint64_t value) { - auto expr = new ConstExpr(Const(Const::I64(), value, GetLocation())); + auto expr = new ConstExpr(Const::I64(value, GetLocation())); expr->loc = GetLocation(); current_init_expr->push_back(expr); return Result::Ok; @@ -973,9 +945,11 @@ Result BinaryReaderIR::OnLocalName(Index func_index, } Result BinaryReaderIR::OnExceptionType(Index index, TypeVector& sig) { - auto except = new Exception(sig); - module->excepts.push_back(except); - module->fields.push_back(new ExceptionModuleField(except)); + auto field = MakeUnique<ExceptionModuleField>(GetLocation()); + auto&& except = field->except; + except.sig = sig; + module->excepts.push_back(&except); + module->fields.push_back(field.release()); return Result::Ok; } diff --git a/src/binary-reader-linker.cc b/src/binary-reader-linker.cc index 065569db..05ccf438 100644 --- a/src/binary-reader-linker.cc +++ b/src/binary-reader-linker.cc @@ -220,7 +220,7 @@ Result BinaryReaderLinker::OnElemSegmentFunctionIndexCount(Index index, Result BinaryReaderLinker::OnMemory(Index index, const Limits* page_limits) { Section* sec = current_section_; - sec->data.memory_limits = *page_limits; + sec->data.initial = page_limits->initial; binary_->memory_page_count = page_limits->initial; return Result::Ok; } diff --git a/src/binary-writer-spec.cc b/src/binary-writer-spec.cc index 08887852..e1f39725 100644 --- a/src/binary-writer-spec.cc +++ b/src/binary-writer-spec.cc @@ -64,7 +64,7 @@ class BinaryWriterSpec { BinaryWriterSpec(const char* source_filename, const WriteBinarySpecOptions* spec_options); - Result WriteScript(Script* script); + Result WriteScript(const Script& script); private: std::string GetModuleFilename(const char* extension); @@ -73,18 +73,18 @@ class BinaryWriterSpec { void WriteSeparator(); void WriteEscapedString(string_view); void WriteCommandType(const Command& command); - void WriteLocation(const Location* loc); - void WriteVar(const Var* var); + void WriteLocation(const Location& loc); + void WriteVar(const Var& var); void WriteTypeObject(Type type); - void WriteConst(const Const* const_); + void WriteConst(const Const& const_); void WriteConstVector(const ConstVector& consts); - void WriteAction(const Action* action); - void WriteActionResultType(Script* script, const Action* action); - void WriteModule(string_view filename, const Module* module); + void WriteAction(const Action& action); + void WriteActionResultType(const Script& script, const Action& action); + void WriteModule(string_view filename, const Module& module); void WriteScriptModule(string_view filename, - const ScriptModule* script_module); - void WriteInvalidModule(const ScriptModule* module, string_view text); - void WriteCommands(Script* script); + const ScriptModule& script_module); + void WriteInvalidModule(const ScriptModule& module, string_view text); + void WriteCommands(const Script& script); MemoryStream json_stream_; std::string source_filename_; @@ -170,16 +170,16 @@ void BinaryWriterSpec::WriteCommandType(const Command& command) { WriteString(s_command_names[static_cast<size_t>(command.type)]); } -void BinaryWriterSpec::WriteLocation(const Location* loc) { +void BinaryWriterSpec::WriteLocation(const Location& loc) { WriteKey("line"); - json_stream_.Writef("%d", loc->line); + json_stream_.Writef("%d", loc.line); } -void BinaryWriterSpec::WriteVar(const Var* var) { - if (var->is_index()) - json_stream_.Writef("\"%" PRIindex "\"", var->index()); +void BinaryWriterSpec::WriteVar(const Var& var) { + if (var.is_index()) + json_stream_.Writef("\"%" PRIindex "\"", var.index()); else - WriteEscapedString(var->name()); + WriteEscapedString(var.name()); } void BinaryWriterSpec::WriteTypeObject(Type type) { @@ -189,25 +189,25 @@ void BinaryWriterSpec::WriteTypeObject(Type type) { json_stream_.Writef("}"); } -void BinaryWriterSpec::WriteConst(const Const* const_) { +void BinaryWriterSpec::WriteConst(const Const& const_) { json_stream_.Writef("{"); WriteKey("type"); /* Always write the values as strings, even though they may be representable * as JSON numbers. This way the formatting is consistent. */ - switch (const_->type) { + switch (const_.type) { case Type::I32: WriteString("i32"); WriteSeparator(); WriteKey("value"); - json_stream_.Writef("\"%u\"", const_->u32); + json_stream_.Writef("\"%u\"", const_.u32); break; case Type::I64: WriteString("i64"); WriteSeparator(); WriteKey("value"); - json_stream_.Writef("\"%" PRIu64 "\"", const_->u64); + json_stream_.Writef("\"%" PRIu64 "\"", const_.u64); break; case Type::F32: { @@ -215,7 +215,7 @@ void BinaryWriterSpec::WriteConst(const Const* const_) { WriteString("f32"); WriteSeparator(); WriteKey("value"); - json_stream_.Writef("\"%u\"", const_->f32_bits); + json_stream_.Writef("\"%u\"", const_.f32_bits); break; } @@ -224,7 +224,7 @@ void BinaryWriterSpec::WriteConst(const Const* const_) { WriteString("f64"); WriteSeparator(); WriteKey("value"); - json_stream_.Writef("\"%" PRIu64 "\"", const_->f64_bits); + json_stream_.Writef("\"%" PRIu64 "\"", const_.f64_bits); break; } @@ -238,7 +238,7 @@ void BinaryWriterSpec::WriteConst(const Const* const_) { void BinaryWriterSpec::WriteConstVector(const ConstVector& consts) { json_stream_.Writef("["); for (size_t i = 0; i < consts.size(); ++i) { - const Const* const_ = &consts[i]; + const Const& const_ = consts[i]; WriteConst(const_); if (i != consts.size() - 1) WriteSeparator(); @@ -246,43 +246,43 @@ void BinaryWriterSpec::WriteConstVector(const ConstVector& consts) { json_stream_.Writef("]"); } -void BinaryWriterSpec::WriteAction(const Action* action) { +void BinaryWriterSpec::WriteAction(const Action& action) { WriteKey("action"); json_stream_.Writef("{"); WriteKey("type"); - if (action->type == ActionType::Invoke) { + if (action.type() == ActionType::Invoke) { WriteString("invoke"); } else { - assert(action->type == ActionType::Get); + assert(action.type() == ActionType::Get); WriteString("get"); } WriteSeparator(); - if (action->module_var.is_name()) { + if (action.module_var.is_name()) { WriteKey("module"); - WriteVar(&action->module_var); + WriteVar(action.module_var); WriteSeparator(); } - if (action->type == ActionType::Invoke) { + if (action.type() == ActionType::Invoke) { WriteKey("field"); - WriteEscapedString(action->name); + WriteEscapedString(action.name); WriteSeparator(); WriteKey("args"); - WriteConstVector(action->invoke->args); + WriteConstVector(cast<InvokeAction>(&action)->args); } else { WriteKey("field"); - WriteEscapedString(action->name); + WriteEscapedString(action.name); } json_stream_.Writef("}"); } -void BinaryWriterSpec::WriteActionResultType(Script* script, - const Action* action) { - const Module* module = script->GetModule(action->module_var); +void BinaryWriterSpec::WriteActionResultType(const Script& script, + const Action& action) { + const Module* module = script.GetModule(action.module_var); const Export* export_; json_stream_.Writef("["); - switch (action->type) { + switch (action.type()) { case ActionType::Invoke: { - export_ = module->GetExport(action->name); + export_ = module->GetExport(action.name); assert(export_->kind == ExternalKind::Func); const Func* func = module->GetFunc(export_->var); Index num_results = func->GetNumResults(); @@ -292,7 +292,7 @@ void BinaryWriterSpec::WriteActionResultType(Script* script, } case ActionType::Get: { - export_ = module->GetExport(action->name); + export_ = module->GetExport(action.name); assert(export_->kind == ExternalKind::Global); const Global* global = module->GetGlobal(export_->var); WriteTypeObject(global->type); @@ -302,26 +302,27 @@ void BinaryWriterSpec::WriteActionResultType(Script* script, json_stream_.Writef("]"); } -void BinaryWriterSpec::WriteModule(string_view filename, const Module* module) { +void BinaryWriterSpec::WriteModule(string_view filename, const Module& module) { MemoryStream memory_stream; - result_ = WriteBinaryModule(&memory_stream.writer(), module, + result_ = WriteBinaryModule(&memory_stream.writer(), &module, &spec_options_->write_binary_options); if (Succeeded(result_) && write_modules_) result_ = memory_stream.WriteToFile(filename); } void BinaryWriterSpec::WriteScriptModule(string_view filename, - const ScriptModule* script_module) { - switch (script_module->type) { - case ScriptModule::Type::Text: - WriteModule(filename, script_module->text); + const ScriptModule& script_module) { + switch (script_module.type()) { + case ScriptModuleType::Text: + WriteModule(filename, cast<TextScriptModule>(&script_module)->module); break; - case ScriptModule::Type::Binary: + case ScriptModuleType::Binary: if (write_modules_) { FileStream file_stream(filename); if (file_stream.is_open()) { - file_stream.WriteData(script_module->binary.data, ""); + file_stream.WriteData(cast<BinaryScriptModule>(&script_module)->data, + ""); result_ = file_stream.result(); } else { result_ = Result::Error; @@ -329,11 +330,12 @@ void BinaryWriterSpec::WriteScriptModule(string_view filename, } break; - case ScriptModule::Type::Quoted: + case ScriptModuleType::Quoted: if (write_modules_) { FileStream file_stream(filename); if (file_stream.is_open()) { - file_stream.WriteData(script_module->quoted.data, ""); + file_stream.WriteData(cast<QuotedScriptModule>(&script_module)->data, + ""); result_ = file_stream.result(); } else { result_ = Result::Error; @@ -343,28 +345,28 @@ void BinaryWriterSpec::WriteScriptModule(string_view filename, } } -void BinaryWriterSpec::WriteInvalidModule(const ScriptModule* module, +void BinaryWriterSpec::WriteInvalidModule(const ScriptModule& module, string_view text) { const char* extension = ""; const char* module_type = ""; - switch (module->type) { - case ScriptModule::Type::Text: + switch (module.type()) { + case ScriptModuleType::Text: extension = kWasmExtension; module_type = "binary"; break; - case ScriptModule::Type::Binary: + case ScriptModuleType::Binary: extension = kWasmExtension; module_type = "binary"; break; - case ScriptModule::Type::Quoted: + case ScriptModuleType::Quoted: extension = kWastExtension; module_type = "text"; break; } - WriteLocation(&module->GetLocation()); + WriteLocation(module.location()); WriteSeparator(); std::string filename = GetModuleFilename(extension); WriteKey("filename"); @@ -378,13 +380,13 @@ void BinaryWriterSpec::WriteInvalidModule(const ScriptModule* module, WriteScriptModule(filename, module); } -void BinaryWriterSpec::WriteCommands(Script* script) { +void BinaryWriterSpec::WriteCommands(const Script& script) { json_stream_.Writef("{\"source_filename\": "); WriteEscapedString(source_filename_); json_stream_.Writef(",\n \"commands\": [\n"); Index last_module_index = kInvalidIndex; - for (size_t i = 0; i < script->commands.size(); ++i) { - const Command* command = script->commands[i].get(); + for (size_t i = 0; i < script.commands.size(); ++i) { + const Command* command = script.commands[i].get(); if (i != 0) { WriteSeparator(); @@ -397,13 +399,13 @@ void BinaryWriterSpec::WriteCommands(Script* script) { switch (command->type) { case CommandType::Module: { - Module* module = cast<ModuleCommand>(command)->module; + const Module& module = cast<ModuleCommand>(command)->module; std::string filename = GetModuleFilename(kWasmExtension); - WriteLocation(&module->loc); + WriteLocation(module.loc); WriteSeparator(); - if (!module->name.empty()) { + if (!module.name.empty()) { WriteKey("name"); - WriteEscapedString(module->name); + WriteEscapedString(module.name); WriteSeparator(); } WriteKey("filename"); @@ -415,8 +417,8 @@ void BinaryWriterSpec::WriteCommands(Script* script) { } case CommandType::Action: { - const Action* action = cast<ActionCommand>(command)->action; - WriteLocation(&action->loc); + const Action& action = *cast<ActionCommand>(command)->action; + WriteLocation(action.loc); WriteSeparator(); WriteAction(action); break; @@ -425,11 +427,11 @@ void BinaryWriterSpec::WriteCommands(Script* script) { case CommandType::Register: { auto* register_command = cast<RegisterCommand>(command); const Var& var = register_command->var; - WriteLocation(&var.loc); + WriteLocation(var.loc); WriteSeparator(); if (var.is_name()) { WriteKey("name"); - WriteVar(&var); + WriteVar(var); WriteSeparator(); } else { /* If we're not registering by name, then we should only be @@ -444,7 +446,7 @@ void BinaryWriterSpec::WriteCommands(Script* script) { case CommandType::AssertMalformed: { auto* assert_malformed_command = cast<AssertMalformedCommand>(command); - WriteInvalidModule(assert_malformed_command->module, + WriteInvalidModule(*assert_malformed_command->module, assert_malformed_command->text); num_modules_++; break; @@ -452,7 +454,7 @@ void BinaryWriterSpec::WriteCommands(Script* script) { case CommandType::AssertInvalid: { auto* assert_invalid_command = cast<AssertInvalidCommand>(command); - WriteInvalidModule(assert_invalid_command->module, + WriteInvalidModule(*assert_invalid_command->module, assert_invalid_command->text); num_modules_++; break; @@ -461,7 +463,7 @@ void BinaryWriterSpec::WriteCommands(Script* script) { case CommandType::AssertUnlinkable: { auto* assert_unlinkable_command = cast<AssertUnlinkableCommand>(command); - WriteInvalidModule(assert_unlinkable_command->module, + WriteInvalidModule(*assert_unlinkable_command->module, assert_unlinkable_command->text); num_modules_++; break; @@ -470,7 +472,7 @@ void BinaryWriterSpec::WriteCommands(Script* script) { case CommandType::AssertUninstantiable: { auto* assert_uninstantiable_command = cast<AssertUninstantiableCommand>(command); - WriteInvalidModule(assert_uninstantiable_command->module, + WriteInvalidModule(*assert_uninstantiable_command->module, assert_uninstantiable_command->text); num_modules_++; break; @@ -478,46 +480,46 @@ void BinaryWriterSpec::WriteCommands(Script* script) { case CommandType::AssertReturn: { auto* assert_return_command = cast<AssertReturnCommand>(command); - WriteLocation(&assert_return_command->action->loc); + WriteLocation(assert_return_command->action->loc); WriteSeparator(); - WriteAction(assert_return_command->action); + WriteAction(*assert_return_command->action); WriteSeparator(); WriteKey("expected"); - WriteConstVector(*assert_return_command->expected); + WriteConstVector(assert_return_command->expected); break; } case CommandType::AssertReturnCanonicalNan: { auto* assert_return_canonical_nan_command = cast<AssertReturnCanonicalNanCommand>(command); - WriteLocation(&assert_return_canonical_nan_command->action->loc); + WriteLocation(assert_return_canonical_nan_command->action->loc); WriteSeparator(); - WriteAction(assert_return_canonical_nan_command->action); + WriteAction(*assert_return_canonical_nan_command->action); WriteSeparator(); WriteKey("expected"); WriteActionResultType(script, - assert_return_canonical_nan_command->action); + *assert_return_canonical_nan_command->action); break; } case CommandType::AssertReturnArithmeticNan: { auto* assert_return_arithmetic_nan_command = cast<AssertReturnArithmeticNanCommand>(command); - WriteLocation(&assert_return_arithmetic_nan_command->action->loc); + WriteLocation(assert_return_arithmetic_nan_command->action->loc); WriteSeparator(); - WriteAction(assert_return_arithmetic_nan_command->action); + WriteAction(*assert_return_arithmetic_nan_command->action); WriteSeparator(); WriteKey("expected"); WriteActionResultType(script, - assert_return_arithmetic_nan_command->action); + *assert_return_arithmetic_nan_command->action); break; } case CommandType::AssertTrap: { auto* assert_trap_command = cast<AssertTrapCommand>(command); - WriteLocation(&assert_trap_command->action->loc); + WriteLocation(assert_trap_command->action->loc); WriteSeparator(); - WriteAction(assert_trap_command->action); + WriteAction(*assert_trap_command->action); WriteSeparator(); WriteKey("text"); WriteEscapedString(assert_trap_command->text); @@ -527,9 +529,9 @@ void BinaryWriterSpec::WriteCommands(Script* script) { case CommandType::AssertExhaustion: { auto* assert_exhaustion_command = cast<AssertExhaustionCommand>(command); - WriteLocation(&assert_exhaustion_command->action->loc); + WriteLocation(assert_exhaustion_command->action->loc); WriteSeparator(); - WriteAction(assert_exhaustion_command->action); + WriteAction(*assert_exhaustion_command->action); break; } } @@ -539,7 +541,7 @@ void BinaryWriterSpec::WriteCommands(Script* script) { json_stream_.Writef("]}\n"); } -Result BinaryWriterSpec::WriteScript(Script* script) { +Result BinaryWriterSpec::WriteScript(const Script& script) { WriteCommands(script); if (spec_options_->json_filename) { json_stream_.WriteToFile(spec_options_->json_filename); @@ -554,7 +556,7 @@ Result WriteBinarySpecScript(Script* script, const WriteBinarySpecOptions* spec_options) { assert(source_filename); BinaryWriterSpec binary_writer_spec(source_filename, spec_options); - return binary_writer_spec.WriteScript(script); + return binary_writer_spec.WriteScript(*script); } } // namespace wabt diff --git a/src/binary-writer.cc b/src/binary-writer.cc index 2a8e04da..6fb4235d 100644 --- a/src/binary-writer.cc +++ b/src/binary-writer.cc @@ -422,14 +422,14 @@ Index BinaryWriter::GetLocalIndex(const Func* func, const Var& var) { void BinaryWriter::WriteExpr(const Module* module, const Func* func, const Expr* expr) { - switch (expr->type) { + switch (expr->type()) { case ExprType::Binary: WriteOpcode(&stream_, cast<BinaryExpr>(expr)->opcode); break; 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); + write_inline_signature_type(&stream_, cast<BlockExpr>(expr)->block.sig); + WriteExprList(module, func, cast<BlockExpr>(expr)->block.exprs); WriteOpcode(&stream_, Opcode::End); break; case ExprType::Br: @@ -445,9 +445,9 @@ void BinaryWriter::WriteExpr(const Module* module, case ExprType::BrTable: { auto br_table_expr = cast<BrTableExpr>(expr); WriteOpcode(&stream_, Opcode::BrTable); - WriteU32Leb128(&stream_, br_table_expr->targets->size(), "num targets"); + WriteU32Leb128(&stream_, br_table_expr->targets.size(), "num targets"); Index depth; - for (const Var& var : *br_table_expr->targets) { + for (const Var& var : br_table_expr->targets) { depth = GetLabelVarDepth(&var); WriteU32Leb128(&stream_, depth, "break depth"); } @@ -526,8 +526,8 @@ void BinaryWriter::WriteExpr(const Module* module, case ExprType::If: { 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); + write_inline_signature_type(&stream_, if_expr->true_.sig); + WriteExprList(module, func, if_expr->true_.exprs); if (!if_expr->false_.empty()) { WriteOpcode(&stream_, Opcode::Else); WriteExprList(module, func, if_expr->false_); @@ -545,8 +545,8 @@ void BinaryWriter::WriteExpr(const Module* module, } 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); + write_inline_signature_type(&stream_, cast<LoopExpr>(expr)->block.sig); + WriteExprList(module, func, cast<LoopExpr>(expr)->block.exprs); WriteOpcode(&stream_, Opcode::End); break; case ExprType::Nop: @@ -597,17 +597,17 @@ void BinaryWriter::WriteExpr(const Module* module, case ExprType::TryBlock: { 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); - for (Catch* catch_ : try_expr->catches) { - if (catch_->IsCatchAll()) { + write_inline_signature_type(&stream_, try_expr->block.sig); + WriteExprList(module, func, try_expr->block.exprs); + for (const Catch& catch_ : try_expr->catches) { + if (catch_.IsCatchAll()) { WriteOpcode(&stream_, Opcode::CatchAll); } else { WriteOpcode(&stream_, Opcode::Catch); - WriteU32Leb128(&stream_, GetExceptVarDepth(&catch_->var), + WriteU32Leb128(&stream_, GetExceptVarDepth(&catch_.var), "catch exception"); } - WriteExprList(module, func, catch_->exprs); + WriteExprList(module, func, catch_.exprs); } WriteOpcode(&stream_, Opcode::End); break; @@ -767,23 +767,28 @@ Result BinaryWriter::WriteModule(const Module* module) { PrintChars::Yes); WriteStr(&stream_, import->field_name, "import field name", PrintChars::Yes); - stream_.WriteU8Enum(import->kind, "import kind"); - switch (import->kind) { + stream_.WriteU8Enum(import->kind(), "import kind"); + switch (import->kind()) { case ExternalKind::Func: - WriteU32Leb128(&stream_, module->GetFuncTypeIndex(import->func->decl), + WriteU32Leb128(&stream_, module->GetFuncTypeIndex( + cast<FuncImport>(import)->func.decl), "import signature index"); break; + case ExternalKind::Table: - WriteTable(import->table); + WriteTable(&cast<TableImport>(import)->table); break; + case ExternalKind::Memory: - WriteMemory(import->memory); + WriteMemory(&cast<MemoryImport>(import)->memory); break; + case ExternalKind::Global: - WriteGlobalHeader(import->global); + WriteGlobalHeader(&cast<GlobalImport>(import)->global); break; + case ExternalKind::Except: - WriteExceptType(&import->except->sig); + WriteExceptType(&cast<ExceptionImport>(import)->except.sig); break; } } diff --git a/src/common.h b/src/common.h index d65306bc..370e0cbd 100644 --- a/src/common.h +++ b/src/common.h @@ -120,8 +120,19 @@ void Destruct(T& placement) { placement.~T(); } +// This is named MakeUnique instead of make_unique because make_unique has the +// potential to conflict with std::make_unique if it is defined. +// +// On gcc/clang, we currently compile with c++11, which doesn't define +// std::make_unique, but on MSVC the newest C++ version is always used, which +// includes std::make_unique. If an argument from the std namespace is used, it +// will cause ADL to find std::make_unique, and an unqualified call to +// make_unique will be ambiguous. We can work around this by fully qualifying +// the call (i.e. wabt::make_unique), but it's simpler to just use a different +// name. It's also more consistent with other names in the wabt namespace, +// which use CamelCase. template <typename T, typename... Args> -std::unique_ptr<T> make_unique(Args&&... args) { +std::unique_ptr<T> MakeUnique(Args&&... args) { return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); } @@ -251,9 +262,9 @@ enum class ExternalKind { static const int kExternalKindCount = WABT_ENUM_COUNT(ExternalKind); struct Limits { - uint64_t initial; - uint64_t max; - bool has_max; + uint64_t initial = 0; + uint64_t max = 0; + bool has_max = false; }; enum { WABT_USE_NATURAL_ALIGNMENT = 0xFFFFFFFF }; diff --git a/src/expr-visitor.cc b/src/expr-visitor.cc index af8d16a5..f62dd166 100644 --- a/src/expr-visitor.cc +++ b/src/expr-visitor.cc @@ -30,7 +30,7 @@ namespace wabt { ExprVisitor::ExprVisitor(Delegate* delegate) : delegate_(delegate) {} Result ExprVisitor::VisitExpr(Expr* expr) { - switch (expr->type) { + switch (expr->type()) { case ExprType::Binary: CHECK_RESULT(delegate_->OnBinaryExpr(cast<BinaryExpr>(expr))); break; @@ -38,7 +38,7 @@ Result ExprVisitor::VisitExpr(Expr* expr) { case ExprType::Block: { auto block_expr = cast<BlockExpr>(expr); CHECK_RESULT(delegate_->BeginBlockExpr(block_expr)); - CHECK_RESULT(VisitExprList(block_expr->block->exprs)); + CHECK_RESULT(VisitExprList(block_expr->block.exprs)); CHECK_RESULT(delegate_->EndBlockExpr(block_expr)); break; } @@ -99,7 +99,7 @@ Result ExprVisitor::VisitExpr(Expr* expr) { case ExprType::If: { auto if_expr = cast<IfExpr>(expr); CHECK_RESULT(delegate_->BeginIfExpr(if_expr)); - CHECK_RESULT(VisitExprList(if_expr->true_->exprs)); + CHECK_RESULT(VisitExprList(if_expr->true_.exprs)); CHECK_RESULT(delegate_->AfterIfTrueExpr(if_expr)); CHECK_RESULT(VisitExprList(if_expr->false_)); CHECK_RESULT(delegate_->EndIfExpr(if_expr)); @@ -113,7 +113,7 @@ Result ExprVisitor::VisitExpr(Expr* expr) { case ExprType::Loop: { auto loop_expr = cast<LoopExpr>(expr); CHECK_RESULT(delegate_->BeginLoopExpr(loop_expr)); - CHECK_RESULT(VisitExprList(loop_expr->block->exprs)); + CHECK_RESULT(VisitExprList(loop_expr->block.exprs)); CHECK_RESULT(delegate_->EndLoopExpr(loop_expr)); break; } @@ -157,10 +157,10 @@ Result ExprVisitor::VisitExpr(Expr* expr) { case ExprType::TryBlock: { auto try_expr = cast<TryExpr>(expr); CHECK_RESULT(delegate_->BeginTryExpr(try_expr)); - CHECK_RESULT(VisitExprList(try_expr->block->exprs)); - for (Catch* catch_ : try_expr->catches) { - CHECK_RESULT(delegate_->OnCatchExpr(try_expr, catch_)); - CHECK_RESULT(VisitExprList(catch_->exprs)); + CHECK_RESULT(VisitExprList(try_expr->block.exprs)); + for (Catch& catch_ : try_expr->catches) { + CHECK_RESULT(delegate_->OnCatchExpr(try_expr, &catch_)); + CHECK_RESULT(VisitExprList(catch_.exprs)); } CHECK_RESULT(delegate_->EndTryExpr(try_expr)); break; diff --git a/src/generate-names.cc b/src/generate-names.cc index c495e565..2ed00222 100644 --- a/src/generate-names.cc +++ b/src/generate-names.cc @@ -133,17 +133,17 @@ void NameGenerator::GenerateAndBindLocalNames(BindingHash* bindings, } Result NameGenerator::BeginBlockExpr(BlockExpr* expr) { - MaybeGenerateName("$B", label_count_++, &expr->block->label); + MaybeGenerateName("$B", label_count_++, &expr->block.label); return Result::Ok; } Result NameGenerator::BeginLoopExpr(LoopExpr* expr) { - MaybeGenerateName("$L", label_count_++, &expr->block->label); + MaybeGenerateName("$L", label_count_++, &expr->block.label); return Result::Ok; } Result NameGenerator::BeginIfExpr(IfExpr* expr) { - MaybeGenerateName("$I", label_count_++, &expr->true_->label); + MaybeGenerateName("$I", label_count_++, &expr->true_.label); return Result::Ok; } diff --git a/src/interpreter.h b/src/interpreter.h index 6eb10029..cca4f173 100644 --- a/src/interpreter.h +++ b/src/interpreter.h @@ -192,7 +192,7 @@ struct FuncImport : Import { }; struct TableImport : Import { - TableImport() : Import(ExternalKind::Table) { ZeroMemory(limits); } + TableImport() : Import(ExternalKind::Table) {} TableImport(string_view module_name, string_view field_name) : Import(ExternalKind::Table, module_name, field_name) {} @@ -200,7 +200,7 @@ struct TableImport : Import { }; struct MemoryImport : Import { - MemoryImport() : Import(ExternalKind::Memory) { ZeroMemory(limits); } + MemoryImport() : Import(ExternalKind::Memory) {} MemoryImport(string_view module_name, string_view field_name) : Import(ExternalKind::Memory, module_name, field_name) {} @@ -67,7 +67,7 @@ const char* GetExprTypeName(ExprType type) { } const char* GetExprTypeName(const Expr& expr) { - return GetExprTypeName(expr.type); + return GetExprTypeName(expr.type()); } bool FuncSignature::operator==(const FuncSignature& rhs) const { @@ -193,102 +193,112 @@ Index Module::GetFuncTypeIndex(const FuncDeclaration& decl) const { void Module::AppendField(DataSegmentModuleField* field) { fields.push_back(field); - data_segments.push_back(field->data_segment); + data_segments.push_back(&field->data_segment); } void Module::AppendField(ElemSegmentModuleField* field) { fields.push_back(field); - elem_segments.push_back(field->elem_segment); + elem_segments.push_back(&field->elem_segment); } void Module::AppendField(ExceptionModuleField* field) { - auto except = field->except; - if (!except->name.empty()) - except_bindings.emplace(except->name, Binding(field->loc, excepts.size())); - excepts.push_back(except); + auto&& except = field->except; + if (!except.name.empty()) + except_bindings.emplace(except.name, Binding(field->loc, excepts.size())); + excepts.push_back(&except); fields.push_back(field); } void Module::AppendField(ExportModuleField* field) { // Exported names are allowed to be empty. - auto export_ = field->export_; - export_bindings.emplace(export_->name, Binding(field->loc, exports.size())); - exports.push_back(export_); + auto&& export_ = field->export_; + export_bindings.emplace(export_.name, Binding(field->loc, exports.size())); + exports.push_back(&export_); fields.push_back(field); } void Module::AppendField(FuncModuleField* field) { - auto func = field->func; - if (!func->name.empty()) - func_bindings.emplace(func->name, Binding(field->loc, funcs.size())); - funcs.push_back(func); + auto&& func = field->func; + if (!func.name.empty()) + func_bindings.emplace(func.name, Binding(field->loc, funcs.size())); + funcs.push_back(&func); fields.push_back(field); } void Module::AppendField(FuncTypeModuleField* field) { - auto func_type = field->func_type; - if (!func_type->name.empty()) { - func_type_bindings.emplace(func_type->name, + auto&& func_type = field->func_type; + if (!func_type.name.empty()) { + func_type_bindings.emplace(func_type.name, Binding(field->loc, func_types.size())); } - func_types.push_back(func_type); + func_types.push_back(&func_type); fields.push_back(field); } void Module::AppendField(GlobalModuleField* field) { - auto global = field->global; - if (!global->name.empty()) - global_bindings.emplace(global->name, Binding(field->loc, globals.size())); - globals.push_back(global); + auto&& global = field->global; + if (!global.name.empty()) + global_bindings.emplace(global.name, Binding(field->loc, globals.size())); + globals.push_back(&global); fields.push_back(field); } void Module::AppendField(ImportModuleField* field) { - auto import = field->import; - std::string* name = nullptr; + auto* import = field->import.get(); + const std::string* name = nullptr; BindingHash* bindings = nullptr; Index index = kInvalidIndex; - switch (import->kind) { - case ExternalKind::Func: - name = &import->func->name; + switch (import->kind()) { + case ExternalKind::Func: { + auto&& func = cast<FuncImport>(import)->func; + name = &func.name; bindings = &func_bindings; index = funcs.size(); - funcs.push_back(import->func); + funcs.push_back(&func); ++num_func_imports; break; + } - case ExternalKind::Table: - name = &import->table->name; + case ExternalKind::Table: { + auto&& table = cast<TableImport>(import)->table; + name = &table.name; bindings = &table_bindings; index = tables.size(); - tables.push_back(import->table); + tables.push_back(&table); ++num_table_imports; break; + } - case ExternalKind::Memory: - name = &import->memory->name; + case ExternalKind::Memory: { + auto&& memory = cast<MemoryImport>(import)->memory; + name = &memory.name; bindings = &memory_bindings; index = memories.size(); - memories.push_back(import->memory); + memories.push_back(&memory); ++num_memory_imports; break; + } - case ExternalKind::Global: - name = &import->global->name; + case ExternalKind::Global: { + auto&& global = cast<GlobalImport>(import)->global; + name = &global.name; bindings = &global_bindings; index = globals.size(); - globals.push_back(import->global); + globals.push_back(&global); ++num_global_imports; break; + } - case ExternalKind::Except: - name = &import->except->name; + case ExternalKind::Except: { + auto&& except = cast<ExceptionImport>(import)->except; + name = &except.name; bindings = &except_bindings; index = excepts.size(); - excepts.push_back(import->except); + excepts.push_back(&except); ++num_except_imports; break; + } } assert(name && bindings && index != kInvalidIndex); @@ -299,10 +309,10 @@ void Module::AppendField(ImportModuleField* field) { } void Module::AppendField(MemoryModuleField* field) { - auto memory = field->memory; - if (!memory->name.empty()) - memory_bindings.emplace(memory->name, Binding(field->loc, memories.size())); - memories.push_back(memory); + auto&& memory = field->memory; + if (!memory.name.empty()) + memory_bindings.emplace(memory.name, Binding(field->loc, memories.size())); + memories.push_back(&memory); fields.push_back(field); } @@ -312,15 +322,15 @@ void Module::AppendField(StartModuleField* field) { } void Module::AppendField(TableModuleField* field) { - auto table = field->table; - if (!table->name.empty()) - table_bindings.emplace(table->name, Binding(field->loc, tables.size())); - tables.push_back(table); + auto&& table = field->table; + if (!table.name.empty()) + table_bindings.emplace(table.name, Binding(field->loc, tables.size())); + tables.push_back(&table); fields.push_back(field); } void Module::AppendField(ModuleField* field) { - switch (field->type) { + switch (field->type()) { case ModuleFieldType::Func: AppendField(dyn_cast<FuncModuleField>(field)); break; @@ -379,7 +389,7 @@ const Module* Script::GetFirstModule() const { Module* Script::GetFirstModule() { for (const std::unique_ptr<Command>& command : commands) { if (auto* module_command = dyn_cast<ModuleCommand>(command.get())) - return module_command->module; + return &module_command->module; } return nullptr; } @@ -389,7 +399,7 @@ const Module* Script::GetModule(const Var& var) const { if (index >= commands.size()) return nullptr; auto* command = cast<ModuleCommand>(commands[index].get()); - return command->module; + return &command->module; } void MakeTypeBindingReverseMapping( @@ -464,128 +474,20 @@ void Var::Destroy() { Destruct(name_); } -Const::Const(I32, uint32_t value, const Location& loc_) +Const::Const(I32Tag, uint32_t value, const Location& loc_) : loc(loc_), type(Type::I32), u32(value) { } -Const::Const(I64, uint64_t value, const Location& loc_) +Const::Const(I64Tag, uint64_t value, const Location& loc_) : loc(loc_), type(Type::I64), u64(value) { } -Const::Const(F32, uint32_t value, const Location& loc_) +Const::Const(F32Tag, uint32_t value, const Location& loc_) : loc(loc_), type(Type::F32), f32_bits(value) { } -Const::Const(F64, uint64_t value, const Location& loc_) +Const::Const(F64Tag, uint64_t value, const Location& loc_) : loc(loc_), type(Type::F64), f64_bits(value) { } -Block::Block(ExprList exprs) : exprs(std::move(exprs)) {} - -Catch::Catch() {} - -Catch::Catch(const Var& var) : var(var) {} - -Catch::Catch(ExprList exprs) : exprs(std::move(exprs)) {} - -Catch::Catch(const Var& var, ExprList exprs) - : var(var), exprs(std::move(exprs)) {} - -IfExpr::~IfExpr() { - delete true_; -} - -TryExpr::~TryExpr() { - delete block; - for (Catch* catch_ : catches) - delete catch_; -} - -Expr::Expr(ExprType type) : type(type) {} - -Expr::Expr(ExprType type, Location loc) : loc(loc), type(type) {} - -Table::Table() { - ZeroMemory(elem_limits); -} - -Memory::Memory() { - ZeroMemory(page_limits); -} - -Import::Import() : kind(ExternalKind::Func), func(nullptr) {} - -Import::~Import() { - switch (kind) { - case ExternalKind::Func: - delete func; - break; - case ExternalKind::Table: - delete table; - break; - case ExternalKind::Memory: - delete memory; - break; - case ExternalKind::Global: - delete global; - break; - case ExternalKind::Except: - delete except; - break; - } -} - -ModuleField::ModuleField(ModuleFieldType type, const Location& loc) - : loc(loc), type(type) {} - -ScriptModule::ScriptModule(Type type) : type(type) { - switch (type) { - case ScriptModule::Type::Text: - text = nullptr; - break; - - case ScriptModule::Type::Binary: - Construct(binary.loc); - Construct(binary.name); - Construct(binary.data); - break; - - case ScriptModule::Type::Quoted: - Construct(quoted.loc); - Construct(quoted.name); - Construct(quoted.data); - break; - } -} - -ScriptModule::~ScriptModule() { - switch (type) { - case ScriptModule::Type::Text: - delete text; - break; - case ScriptModule::Type::Binary: - Destruct(binary.loc); - Destruct(binary.name); - Destruct(binary.data); - break; - case ScriptModule::Type::Quoted: - Destruct(quoted.loc); - Destruct(quoted.name); - Destruct(quoted.data); - break; - } -} - -Action::Action() : type(ActionType::Get), module_var(kInvalidIndex) {} - -Action::~Action() { - switch (type) { - case ActionType::Invoke: - delete invoke; - break; - case ActionType::Get: - break; - } -} - } // namespace wabt @@ -72,17 +72,23 @@ struct Var { typedef std::vector<Var> VarVector; struct Const { - // Struct tags to differentiate constructors. - struct I32 {}; - struct I64 {}; - struct F32 {}; - struct F64 {}; + Const() : Const(I32Tag(), 0, Location()) {} + + static Const I32(uint32_t val = 0, const Location& loc = Location()) { + return Const(I32Tag(), val, loc); + } + + static Const I64(uint64_t val = 0, const Location& loc = Location()) { + return Const(I64Tag(), val, loc); + } + + static Const F32(uint32_t val = 0, const Location& loc = Location()) { + return Const(F32Tag(), val, loc); + } - Const() : Const(I32(), 0, Location()) {} - Const(I32, uint32_t val = 0, const Location& loc = Location()); - Const(I64, uint64_t val = 0, const Location& loc = Location()); - Const(F32, uint32_t val = 0, const Location& loc = Location()); - Const(F64, uint64_t val = 0, const Location& loc = Location()); + static Const F64(uint64_t val = 0, const Location& loc = Location()) { + return Const(F64Tag(), val, loc); + } Location loc; Type type; @@ -92,6 +98,18 @@ struct Const { uint32_t f32_bits; uint64_t f64_bits; }; + + private: + // Struct tags to differentiate constructors. + struct I32Tag {}; + struct I64Tag {}; + struct F32Tag {}; + struct F64Tag {}; + + Const(I32Tag, uint32_t val = 0, const Location& loc = Location()); + Const(I64Tag, uint64_t val = 0, const Location& loc = Location()); + Const(F32Tag, uint32_t val = 0, const Location& loc = Location()); + Const(F64Tag, uint64_t val = 0, const Location& loc = Location()); }; typedef std::vector<Const> ConstVector; @@ -140,7 +158,7 @@ typedef intrusive_list<Expr> ExprList; struct Block { Block() = default; - explicit Block(ExprList exprs); + explicit Block(ExprList exprs) : exprs(std::move(exprs)) {} std::string label; BlockSignature sig; @@ -148,11 +166,9 @@ struct Block { }; struct Catch { - WABT_DISALLOW_COPY_AND_ASSIGN(Catch); - Catch(); - explicit Catch(const Var& var); - explicit Catch(ExprList exprs); - Catch(const Var& var, ExprList exprs); + explicit Catch(const Location& loc = Location()) : loc(loc) {} + explicit Catch(const Var& var, const Location& loc = Location()) + : loc(loc), var(var) {} Location loc; Var var; ExprList exprs; @@ -161,7 +177,7 @@ struct Catch { } }; -typedef std::vector<Catch*> CatchVector; +typedef std::vector<Catch> CatchVector; class Expr : public intrusive_list_base<Expr> { public: @@ -169,12 +185,15 @@ class Expr : public intrusive_list_base<Expr> { Expr() = delete; virtual ~Expr() = default; + ExprType type() const { return type_; } + Location loc; - ExprType type; protected: - explicit Expr(ExprType); - Expr(ExprType, Location); + explicit Expr(ExprType type, const Location& loc = Location()) + : loc(loc), type_(type) {} + + ExprType type_; }; const char* GetExprTypeName(const Expr& expr); @@ -182,10 +201,9 @@ const char* GetExprTypeName(const Expr& expr); template <ExprType TypeEnum> class ExprMixin : public Expr { public: - static bool classof(const Expr* expr) { return expr->type == TypeEnum; } + static bool classof(const Expr* expr) { return expr->type() == TypeEnum; } - ExprMixin() : Expr(TypeEnum) {} - explicit ExprMixin(Location loc) : Expr(TypeEnum, loc) {} + explicit ExprMixin(const Location& loc = Location()) : Expr(TypeEnum, loc) {} }; typedef ExprMixin<ExprType::CurrentMemory> CurrentMemoryExpr; @@ -234,11 +252,10 @@ typedef VarExpr<ExprType::Throw> ThrowExpr; template <ExprType TypeEnum> class BlockExprBase : public ExprMixin<TypeEnum> { public: - explicit BlockExprBase(Block* block, const Location& loc = Location()) - : ExprMixin<TypeEnum>(loc), block(block) {} - ~BlockExprBase() { delete block; } + explicit BlockExprBase(const Location& loc = Location()) + : ExprMixin<TypeEnum>(loc) {} - Block* block; + Block block; }; typedef BlockExprBase<ExprType::Block> BlockExpr; @@ -246,40 +263,28 @@ typedef BlockExprBase<ExprType::Loop> LoopExpr; class IfExpr : public ExprMixin<ExprType::If> { public: - explicit IfExpr(Block* true_block, - ExprList false_expr = ExprList(), - const Location& loc = Location()) - : ExprMixin<ExprType::If>(loc), - true_(true_block), - false_(std::move(false_expr)) {} - - ~IfExpr(); + explicit IfExpr(const Location& loc = Location()) + : ExprMixin<ExprType::If>(loc) {} - Block* true_; + Block true_; ExprList false_; }; class TryExpr : public ExprMixin<ExprType::TryBlock> { public: explicit TryExpr(const Location& loc = Location()) - : ExprMixin<ExprType::TryBlock>(loc), block(nullptr) {} - ~TryExpr(); + : ExprMixin<ExprType::TryBlock>(loc) {} - Block* block; + Block block; CatchVector catches; }; class BrTableExpr : public ExprMixin<ExprType::BrTable> { public: - BrTableExpr(VarVector* targets, - Var default_target, - const Location& loc = Location()) - : ExprMixin<ExprType::BrTable>(loc), - targets(targets), - default_target(default_target) {} - ~BrTableExpr() { delete targets; } + BrTableExpr(const Location& loc = Location()) + : ExprMixin<ExprType::BrTable>(loc) {} - VarVector* targets; + VarVector targets; Var default_target; }; @@ -313,8 +318,7 @@ typedef LoadStoreExpr<ExprType::Store> StoreExpr; struct Exception { Exception() = default; - Exception(const TypeVector& sig) : sig(sig) {} - Exception(string_view name, const TypeVector& sig) : name(name), sig(sig) {} + explicit Exception(string_view name) : name(name.to_string()) {} std::string name; TypeVector sig; @@ -333,6 +337,9 @@ struct FuncSignature { }; struct FuncType { + FuncType() = default; + explicit FuncType(string_view name) : name(name.to_string()) {} + Index GetNumParams() const { return sig.GetNumParams(); } Index GetNumResults() const { return sig.GetNumResults(); } Type GetParamType(Index index) const { return sig.GetParamType(index); } @@ -354,6 +361,9 @@ struct FuncDeclaration { }; struct Func { + Func() = default; + explicit Func(string_view name) : name(name.to_string()) {} + Type GetParamType(Index index) const { return decl.GetParamType(index); } Type GetResultType(Index index) const { return decl.GetResultType(index); } Index GetNumParams() const { return decl.GetNumParams(); } @@ -373,6 +383,9 @@ struct Func { }; struct Global { + Global() = default; + explicit Global(string_view name) : name(name.to_string()) {} + std::string name; Type type = Type::Void; bool mutable_ = false; @@ -380,7 +393,8 @@ struct Global { }; struct Table { - Table(); + Table() = default; + explicit Table(string_view name) : name(name.to_string()) {} std::string name; Limits elem_limits; @@ -393,7 +407,8 @@ struct ElemSegment { }; struct Memory { - Memory(); + Memory() = default; + explicit Memory(string_view name) : name(name.to_string()) {} std::string name; Limits page_limits; @@ -405,24 +420,71 @@ struct DataSegment { std::vector<uint8_t> data; }; -struct Import { +class Import { + public: WABT_DISALLOW_COPY_AND_ASSIGN(Import); - Import(); - ~Import(); + Import() = delete; + virtual ~Import() = default; + + ExternalKind kind() const { return kind_; } std::string module_name; std::string field_name; - ExternalKind kind; - union { - // An imported func has the type Func so it can be more easily included in - // the Module's vector of funcs, but only the FuncDeclaration will have any - // useful information. - Func* func; - Table* table; - Memory* memory; - Global* global; - Exception* except; - }; + + protected: + Import(ExternalKind kind) : kind_(kind) {} + + ExternalKind kind_; +}; + +template <ExternalKind TypeEnum> +class ImportMixin : public Import { + public: + static bool classof(const Import* import) { + return import->kind() == TypeEnum; + } + + ImportMixin() : Import(TypeEnum) {} +}; + +class FuncImport : public ImportMixin<ExternalKind::Func> { + public: + explicit FuncImport(string_view name = string_view()) + : ImportMixin<ExternalKind::Func>(), func(name) {} + + Func func; +}; + +class TableImport : public ImportMixin<ExternalKind::Table> { + public: + explicit TableImport(string_view name = string_view()) + : ImportMixin<ExternalKind::Table>(), table(name) {} + + Table table; +}; + +class MemoryImport : public ImportMixin<ExternalKind::Memory> { + public: + explicit MemoryImport(string_view name = string_view()) + : ImportMixin<ExternalKind::Memory>(), memory(name) {} + + Memory memory; +}; + +class GlobalImport : public ImportMixin<ExternalKind::Global> { + public: + explicit GlobalImport(string_view name = string_view()) + : ImportMixin<ExternalKind::Global>(), global(name) {} + + Global global; +}; + +class ExceptionImport : public ImportMixin<ExternalKind::Except> { + public: + explicit ExceptionImport(string_view name = string_view()) + : ImportMixin<ExternalKind::Except>(), except(name) {} + + Exception except; }; struct Export { @@ -449,13 +511,17 @@ class ModuleField : public intrusive_list_base<ModuleField> { public: WABT_DISALLOW_COPY_AND_ASSIGN(ModuleField); ModuleField() = delete; - virtual ~ModuleField() {} + virtual ~ModuleField() = default; + + ModuleFieldType type() const { return type_; } Location loc; - ModuleFieldType type; protected: - explicit ModuleField(ModuleFieldType, const Location& loc); + ModuleField(ModuleFieldType type, const Location& loc) + : loc(loc), type_(type) {} + + ModuleFieldType type_; }; typedef intrusive_list<ModuleField> ModuleFieldList; @@ -464,7 +530,7 @@ template <ModuleFieldType TypeEnum> class ModuleFieldMixin : public ModuleField { public: static bool classof(const ModuleField* field) { - return field->type == TypeEnum; + return field->type() == TypeEnum; } explicit ModuleFieldMixin(const Location& loc) : ModuleField(TypeEnum, loc) {} @@ -472,105 +538,94 @@ class ModuleFieldMixin : public ModuleField { class FuncModuleField : public ModuleFieldMixin<ModuleFieldType::Func> { public: - explicit FuncModuleField(Func* func, const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::Func>(loc), func(func) {} - ~FuncModuleField() { delete func; } + explicit FuncModuleField(const Location& loc = Location(), + string_view name = string_view()) + : ModuleFieldMixin<ModuleFieldType::Func>(loc), func(name) {} - Func* func; + Func func; }; class GlobalModuleField : public ModuleFieldMixin<ModuleFieldType::Global> { public: - explicit GlobalModuleField(Global* global, - const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::Global>(loc), global(global) {} - ~GlobalModuleField() { delete global; } + explicit GlobalModuleField(const Location& loc = Location(), + string_view name = string_view()) + : ModuleFieldMixin<ModuleFieldType::Global>(loc), global(name) {} - Global* global; + Global global; }; class ImportModuleField : public ModuleFieldMixin<ModuleFieldType::Import> { public: - explicit ImportModuleField(Import* import, + explicit ImportModuleField(const Location& loc = Location()) + : ModuleFieldMixin<ModuleFieldType::Import>(loc) {} + explicit ImportModuleField(std::unique_ptr<Import> import, const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::Import>(loc), import(import) {} - ~ImportModuleField() { delete import; } + : ModuleFieldMixin<ModuleFieldType::Import>(loc), + import(std::move(import)) {} - Import* import; + std::unique_ptr<Import> import; }; class ExportModuleField : public ModuleFieldMixin<ModuleFieldType::Export> { public: - explicit ExportModuleField(Export* export_, - const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::Export>(loc), export_(export_) {} - ~ExportModuleField() { delete export_; } + explicit ExportModuleField(const Location& loc = Location()) + : ModuleFieldMixin<ModuleFieldType::Export>(loc) {} - Export* export_; + Export export_; }; class FuncTypeModuleField : public ModuleFieldMixin<ModuleFieldType::FuncType> { public: - explicit FuncTypeModuleField(FuncType* func_type, - const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::FuncType>(loc), - func_type(func_type) {} - ~FuncTypeModuleField() { delete func_type; } + explicit FuncTypeModuleField(const Location& loc = Location(), + string_view name = string_view()) + : ModuleFieldMixin<ModuleFieldType::FuncType>(loc), func_type(name) {} - FuncType* func_type; + FuncType func_type; }; class TableModuleField : public ModuleFieldMixin<ModuleFieldType::Table> { public: - explicit TableModuleField(Table* table, const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::Table>(loc), table(table) {} - ~TableModuleField() { delete table; } + explicit TableModuleField(const Location& loc = Location(), + string_view name = string_view()) + : ModuleFieldMixin<ModuleFieldType::Table>(loc), table(name) {} - Table* table; + Table table; }; class ElemSegmentModuleField : public ModuleFieldMixin<ModuleFieldType::ElemSegment> { public: - explicit ElemSegmentModuleField(ElemSegment* elem_segment, - const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::ElemSegment>(loc), - elem_segment(elem_segment) {} - ~ElemSegmentModuleField() { delete elem_segment; } + explicit ElemSegmentModuleField(const Location& loc = Location()) + : ModuleFieldMixin<ModuleFieldType::ElemSegment>(loc) {} - ElemSegment* elem_segment; + ElemSegment elem_segment; }; class MemoryModuleField : public ModuleFieldMixin<ModuleFieldType::Memory> { public: - explicit MemoryModuleField(Memory* memory, - const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::Memory>(loc), memory(memory) {} - ~MemoryModuleField() { delete memory; } + explicit MemoryModuleField(const Location& loc = Location(), + string_view name = string_view()) + : ModuleFieldMixin<ModuleFieldType::Memory>(loc), memory(name) {} - Memory* memory; + Memory memory; }; class DataSegmentModuleField : public ModuleFieldMixin<ModuleFieldType::DataSegment> { public: - explicit DataSegmentModuleField(DataSegment* data_segment, - const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::DataSegment>(loc), - data_segment(data_segment) {} - ~DataSegmentModuleField() { delete data_segment; } + explicit DataSegmentModuleField( const Location& loc = Location()) + : ModuleFieldMixin<ModuleFieldType::DataSegment>(loc) {} - DataSegment* data_segment; + DataSegment data_segment; }; class ExceptionModuleField : public ModuleFieldMixin<ModuleFieldType::Except> { public: - explicit ExceptionModuleField(Exception* except, - const Location& loc = Location()) - : ModuleFieldMixin<ModuleFieldType::Except>(loc), except(except) {} - ~ExceptionModuleField() { delete except; } + explicit ExceptionModuleField(const Location& loc = Location(), + string_view name = string_view()) + : ModuleFieldMixin<ModuleFieldType::Except>(loc), except(name) {} - Exception* except; + Exception except; }; class StartModuleField : public ModuleFieldMixin<ModuleFieldType::Start> { @@ -650,65 +705,108 @@ struct Module { BindingHash memory_bindings; }; +enum class ScriptModuleType { + Text, + Binary, + Quoted, +}; + // A ScriptModule is a module that may not yet be decoded. This allows for text // and binary parsing errors to be deferred until validation time. -struct ScriptModule { - enum class Type { - Text, - Binary, - Quoted, - }; - +class ScriptModule { + public: WABT_DISALLOW_COPY_AND_ASSIGN(ScriptModule); - explicit ScriptModule(Type); - ~ScriptModule(); - - const Location& GetLocation() const { - switch (type) { - case Type::Binary: return binary.loc; - case Type::Quoted: return quoted.loc; - default: assert(0); // Fallthrough. - case Type::Text: return text->loc; - } + ScriptModule() = delete; + virtual ~ScriptModule() = default; + + ScriptModuleType type() const { return type_; } + virtual const Location& location() const = 0; + + protected: + explicit ScriptModule(ScriptModuleType type) : type_(type) {} + + ScriptModuleType type_; +}; + +template <ScriptModuleType TypeEnum> +class ScriptModuleMixin : public ScriptModule { + public: + static bool classof(const ScriptModule* script_module) { + return script_module->type() == TypeEnum; } - Type type; + ScriptModuleMixin() : ScriptModule(TypeEnum) {} +}; - union { - Module* text; - struct { - Location loc; - std::string name; - std::vector<uint8_t> data; - } binary, quoted; - }; +class TextScriptModule : public ScriptModuleMixin<ScriptModuleType::Text> { + public: + const Location& location() const override { return module.loc; } + + Module module; }; -enum class ActionType { - Invoke, - Get, +template <ScriptModuleType TypeEnum> +class DataScriptModule : public ScriptModuleMixin<TypeEnum> { + public: + const Location& location() const override { return loc; } + + Location loc; + std::string name; + std::vector<uint8_t> data; }; -struct ActionInvoke { - WABT_DISALLOW_COPY_AND_ASSIGN(ActionInvoke); - ActionInvoke() = default; +typedef DataScriptModule<ScriptModuleType::Binary> BinaryScriptModule; +typedef DataScriptModule<ScriptModuleType::Quoted> QuotedScriptModule; - ConstVector args; +enum class ActionType { + Invoke, + Get, }; -struct Action { +class Action { + public: WABT_DISALLOW_COPY_AND_ASSIGN(Action); - Action(); - ~Action(); + Action() = delete; + virtual ~Action() = default; + + ActionType type() const { return type_; } Location loc; - ActionType type; Var module_var; std::string name; - union { - ActionInvoke* invoke; - struct {} get; - }; + + protected: + explicit Action(ActionType type, const Location& loc = Location()) + : loc(loc), type_(type) {} + + ActionType type_; +}; + +typedef std::unique_ptr<Action> ActionPtr; + +template <ActionType TypeEnum> +class ActionMixin : public Action { + public: + static bool classof(const Action* action) { + return action->type() == TypeEnum; + } + + explicit ActionMixin(const Location& loc = Location()) + : Action(TypeEnum, loc) {} +}; + +class GetAction : public ActionMixin<ActionType::Get> { + public: + explicit GetAction(const Location& loc = Location()) + : ActionMixin<ActionType::Get>(loc) {} +}; + +class InvokeAction : public ActionMixin<ActionType::Invoke> { + public: + explicit InvokeAction(const Location& loc = Location()) + : ActionMixin<ActionType::Invoke>(loc) {} + + ConstVector args; }; enum class CommandType { @@ -734,7 +832,7 @@ class Command { public: WABT_DISALLOW_COPY_AND_ASSIGN(Command); Command() = delete; - virtual ~Command() {} + virtual ~Command() = default; CommandType type; @@ -751,19 +849,13 @@ class CommandMixin : public Command { class ModuleCommand : public CommandMixin<CommandType::Module> { public: - explicit ModuleCommand(Module* module) : module(module) {} - ~ModuleCommand() { delete module; } - - Module* module; + Module module; }; template <CommandType TypeEnum> class ActionCommandBase : public CommandMixin<TypeEnum> { public: - explicit ActionCommandBase(Action* action) : action(action) {} - ~ActionCommandBase() { delete action; } - - Action* action; + ActionPtr action; }; typedef ActionCommandBase<CommandType::Action> ActionCommand; @@ -783,27 +875,14 @@ class RegisterCommand : public CommandMixin<CommandType::Register> { class AssertReturnCommand : public CommandMixin<CommandType::AssertReturn> { public: - AssertReturnCommand(Action* action, ConstVector* expected) - : action(action), expected(expected) {} - ~AssertReturnCommand() { - delete action; - delete expected; - } - - Action* action; - ConstVector* expected; + ActionPtr action; + ConstVector expected; }; template <CommandType TypeEnum> class AssertTrapCommandBase : public CommandMixin<TypeEnum> { public: - AssertTrapCommandBase(Action* action, string_view text) - : action(action), text(text) {} - ~AssertTrapCommandBase() { - delete action; - } - - Action* action; + ActionPtr action; std::string text; }; @@ -814,11 +893,7 @@ typedef AssertTrapCommandBase<CommandType::AssertExhaustion> template <CommandType TypeEnum> class AssertModuleCommand : public CommandMixin<TypeEnum> { public: - AssertModuleCommand(ScriptModule* module, string_view text) - : module(module), text(text) {} - ~AssertModuleCommand() { delete module; } - - ScriptModule* module; + std::unique_ptr<ScriptModule> module; std::string text; }; diff --git a/src/resolve-names.cc b/src/resolve-names.cc index c18dd557..c2d48b5f 100644 --- a/src/resolve-names.cc +++ b/src/resolve-names.cc @@ -203,7 +203,7 @@ void NameResolver::ResolveLocalVar(Var* var) { } Result NameResolver::BeginBlockExpr(BlockExpr* expr) { - PushLabel(expr->block->label); + PushLabel(expr->block.label); return Result::Ok; } @@ -213,7 +213,7 @@ Result NameResolver::EndBlockExpr(BlockExpr* expr) { } Result NameResolver::BeginLoopExpr(LoopExpr* expr) { - PushLabel(expr->block->label); + PushLabel(expr->block.label); return Result::Ok; } @@ -233,7 +233,7 @@ Result NameResolver::OnBrIfExpr(BrIfExpr* expr) { } Result NameResolver::OnBrTableExpr(BrTableExpr* expr) { - for (Var& target : *expr->targets) + for (Var& target : expr->targets) ResolveLabelVar(&target); ResolveLabelVar(&expr->default_target); return Result::Ok; @@ -260,7 +260,7 @@ Result NameResolver::OnGetLocalExpr(GetLocalExpr* expr) { } Result NameResolver::BeginIfExpr(IfExpr* expr) { - PushLabel(expr->true_->label); + PushLabel(expr->true_.label); return Result::Ok; } @@ -285,7 +285,7 @@ Result NameResolver::OnTeeLocalExpr(TeeLocalExpr* expr) { } Result NameResolver::BeginTryExpr(TryExpr* expr) { - PushLabel(expr->block->label); + PushLabel(expr->block.label); return Result::Ok; } @@ -390,14 +390,14 @@ Result NameResolver::VisitModule(Module* module) { } void NameResolver::VisitScriptModule(ScriptModule* script_module) { - if (script_module->type == ScriptModule::Type::Text) - VisitModule(script_module->text); + if (auto* tsm = dyn_cast<TextScriptModule>(script_module)) + VisitModule(&tsm->module); } void NameResolver::VisitCommand(Command* command) { switch (command->type) { case CommandType::Module: - VisitModule(cast<ModuleCommand>(command)->module); + VisitModule(&cast<ModuleCommand>(command)->module); break; case CommandType::Action: @@ -423,16 +423,17 @@ void NameResolver::VisitCommand(Command* command) { * should try to resolve names when possible. */ ErrorHandlerNop new_error_handler; NameResolver new_resolver(lexer_, script_, &new_error_handler); - new_resolver.VisitScriptModule(assert_invalid_command->module); + new_resolver.VisitScriptModule(assert_invalid_command->module.get()); break; } case CommandType::AssertUnlinkable: - VisitScriptModule(cast<AssertUnlinkableCommand>(command)->module); + VisitScriptModule(cast<AssertUnlinkableCommand>(command)->module.get()); break; case CommandType::AssertUninstantiable: - VisitScriptModule(cast<AssertUninstantiableCommand>(command)->module); + VisitScriptModule( + cast<AssertUninstantiableCommand>(command)->module.get()); break; } } diff --git a/src/tools/wasm-link.cc b/src/tools/wasm-link.cc index 87050754..ddba640b 100644 --- a/src/tools/wasm-link.cc +++ b/src/tools/wasm-link.cc @@ -335,10 +335,9 @@ void Linker::WriteMemorySection(const SectionPtrVector& sections) { WriteU32Leb128(&stream_, 1, "memory count"); Limits limits; - ZeroMemory(limits); limits.has_max = true; for (Section* section: sections) { - limits.initial += section->data.memory_limits.initial; + limits.initial += section->data.initial; } limits.max = limits.initial; WriteLimits(&stream_, &limits); diff --git a/src/validator.cc b/src/validator.cc index a1afab1e..8ec4cb51 100644 --- a/src/validator.cc +++ b/src/validator.cc @@ -55,11 +55,6 @@ class Validator { }; }; - struct TryContext { - const TryExpr* try_ = nullptr; - const Catch* catch_ = nullptr; - }; - void WABT_PRINTF_FORMAT(3, 4) PrintError(const Location* loc, const char* fmt, ...); void OnTypecheckerError(const char* msg); @@ -134,8 +129,8 @@ class Validator { void CheckExport(const Location* loc, const Export* export_); void CheckDuplicateExportBindings(const Module* module); - const TypeVector* CheckInvoke(const Action* action); - Result CheckGet(const Action* action, Type* out_type); + const TypeVector* CheckInvoke(const InvokeAction* action); + Result CheckGet(const GetAction* action, Type* out_type); ActionResult CheckAction(const Action* action); void CheckAssertReturnNanCommand(const Action* action); void CheckCommand(const Command* command); @@ -157,7 +152,6 @@ class Validator { // Cached for access by OnTypecheckerError. const Location* expr_loc_ = nullptr; Result result_ = Result::Ok; - std::vector<TryContext> try_contexts_; }; Validator::Validator(ErrorHandler* error_handler, @@ -419,16 +413,16 @@ void Validator::CheckBlockSig(const Location* loc, void Validator::CheckExpr(const Expr* expr) { expr_loc_ = &expr->loc; - switch (expr->type) { + switch (expr->type()) { case ExprType::Binary: typechecker_.OnBinary(cast<BinaryExpr>(expr)->opcode); break; case ExprType::Block: { auto block_expr = cast<BlockExpr>(expr); - CheckBlockSig(&block_expr->loc, Opcode::Block, &block_expr->block->sig); - typechecker_.OnBlock(&block_expr->block->sig); - CheckExprList(&block_expr->loc, block_expr->block->exprs); + CheckBlockSig(&block_expr->loc, Opcode::Block, &block_expr->block.sig); + typechecker_.OnBlock(&block_expr->block.sig); + CheckExprList(&block_expr->loc, block_expr->block.exprs); typechecker_.OnEnd(); break; } @@ -444,7 +438,7 @@ void Validator::CheckExpr(const Expr* expr) { case ExprType::BrTable: { auto br_table_expr = cast<BrTableExpr>(expr); typechecker_.BeginBrTable(); - for (Var& var : *br_table_expr->targets) { + for (const Var& var : br_table_expr->targets) { typechecker_.OnBrTableTarget(var.index()); } typechecker_.OnBrTableTarget(br_table_expr->default_target.index()); @@ -507,9 +501,9 @@ void Validator::CheckExpr(const Expr* expr) { case ExprType::If: { auto if_expr = cast<IfExpr>(expr); - CheckBlockSig(&if_expr->loc, Opcode::If, &if_expr->true_->sig); - typechecker_.OnIf(&if_expr->true_->sig); - CheckExprList(&if_expr->loc, if_expr->true_->exprs); + CheckBlockSig(&if_expr->loc, Opcode::If, &if_expr->true_.sig); + typechecker_.OnIf(&if_expr->true_.sig); + CheckExprList(&if_expr->loc, if_expr->true_.exprs); if (!if_expr->false_.empty()) { typechecker_.OnElse(); CheckExprList(&if_expr->loc, if_expr->false_); @@ -529,9 +523,9 @@ void Validator::CheckExpr(const Expr* expr) { case ExprType::Loop: { auto loop_expr = cast<LoopExpr>(expr); - CheckBlockSig(&loop_expr->loc, Opcode::Loop, &loop_expr->block->sig); - typechecker_.OnLoop(&loop_expr->block->sig); - CheckExprList(&loop_expr->loc, loop_expr->block->exprs); + CheckBlockSig(&loop_expr->loc, Opcode::Loop, &loop_expr->block.sig); + typechecker_.OnLoop(&loop_expr->block.sig); + CheckExprList(&loop_expr->loc, loop_expr->block.exprs); typechecker_.OnEnd(); break; } @@ -589,34 +583,29 @@ void Validator::CheckExpr(const Expr* expr) { case ExprType::TryBlock: { auto try_expr = cast<TryExpr>(expr); - TryContext context; - context.try_ = try_expr; - try_contexts_.push_back(context); - CheckBlockSig(&try_expr->loc, Opcode::Try, &try_expr->block->sig); + CheckBlockSig(&try_expr->loc, Opcode::Try, &try_expr->block.sig); - typechecker_.OnTryBlock(&try_expr->block->sig); - CheckExprList(&try_expr->loc, try_expr->block->exprs); + typechecker_.OnTryBlock(&try_expr->block.sig); + CheckExprList(&try_expr->loc, try_expr->block.exprs); if (try_expr->catches.empty()) PrintError(&try_expr->loc, "TryBlock: doesn't have any catch clauses"); bool found_catch_all = false; - for (const Catch* catch_ : try_expr->catches) { - try_contexts_.back().catch_ = catch_; - typechecker_.OnCatchBlock(&try_expr->block->sig); - if (catch_->IsCatchAll()) { + for (const Catch& catch_ : try_expr->catches) { + typechecker_.OnCatchBlock(&try_expr->block.sig); + if (catch_.IsCatchAll()) { found_catch_all = true; } else { if (found_catch_all) - PrintError(&catch_->loc, "Appears after catch all block"); + PrintError(&catch_.loc, "Appears after catch all block"); const Exception* except = nullptr; - if (Succeeded(CheckExceptVar(&catch_->var, &except))) { + if (Succeeded(CheckExceptVar(&catch_.var, &except))) { typechecker_.OnCatch(&except->sig); } } - CheckExprList(&catch_->loc, catch_->exprs); + CheckExprList(&catch_.loc, catch_.exprs); } typechecker_.OnEnd(); - try_contexts_.pop_back(); break; } @@ -681,7 +670,7 @@ void Validator::CheckConstInitExpr(const Location* loc, const Expr* expr = &exprs.front(); loc = &expr->loc; - switch (expr->type) { + switch (expr->type()) { case ExprType::Const: type = cast<ConstExpr>(expr)->const_.type; break; @@ -754,17 +743,17 @@ void Validator::CheckTable(const Location* loc, const Table* table) { void Validator::CheckElemSegments(const Module* module) { for (const ModuleField& field : module->fields) { if (auto elem_segment_field = dyn_cast<ElemSegmentModuleField>(&field)) { - ElemSegment* elem_segment = elem_segment_field->elem_segment; + auto&& elem_segment = elem_segment_field->elem_segment; const Table* table; - if (!Succeeded(CheckTableVar(&elem_segment->table_var, &table))) + if (!Succeeded(CheckTableVar(&elem_segment.table_var, &table))) continue; - for (const Var& var : elem_segment->vars) { + for (const Var& var : elem_segment.vars) { if (!Succeeded(CheckFuncVar(&var, nullptr))) continue; } - CheckConstInitExpr(&field.loc, elem_segment->offset, Type::I32, + CheckConstInitExpr(&field.loc, elem_segment.offset, Type::I32, "elem segment offset"); } } @@ -779,42 +768,50 @@ void Validator::CheckMemory(const Location* loc, const Memory* memory) { void Validator::CheckDataSegments(const Module* module) { for (const ModuleField& field : module->fields) { if (auto data_segment_field = dyn_cast<DataSegmentModuleField>(&field)) { - DataSegment* data_segment = data_segment_field->data_segment; + auto&& data_segment = data_segment_field->data_segment; const Memory* memory; - if (!Succeeded(CheckMemoryVar(&data_segment->memory_var, &memory))) + if (!Succeeded(CheckMemoryVar(&data_segment.memory_var, &memory))) continue; - CheckConstInitExpr(&field.loc, data_segment->offset, Type::I32, + CheckConstInitExpr(&field.loc, data_segment.offset, Type::I32, "data segment offset"); } } } void Validator::CheckImport(const Location* loc, const Import* import) { - switch (import->kind) { + switch (import->kind()) { case ExternalKind::Except: ++current_except_index_; - CheckExcept(loc, import->except); + CheckExcept(loc, &cast<ExceptionImport>(import)->except); break; - case ExternalKind::Func: - if (import->func->decl.has_func_type) - CheckFuncTypeVar(&import->func->decl.type_var, nullptr); + + case ExternalKind::Func: { + auto* func_import = cast<FuncImport>(import); + if (func_import->func.decl.has_func_type) + CheckFuncTypeVar(&func_import->func.decl.type_var, nullptr); break; + } + case ExternalKind::Table: - CheckTable(loc, import->table); + CheckTable(loc, &cast<TableImport>(import)->table); ++current_table_index_; break; + case ExternalKind::Memory: - CheckMemory(loc, import->memory); + CheckMemory(loc, &cast<MemoryImport>(import)->memory); ++current_memory_index_; break; - case ExternalKind::Global: - if (import->global->mutable_) { + + case ExternalKind::Global: { + auto* global_import = cast<GlobalImport>(import); + if (global_import->global.mutable_) { PrintError(loc, "mutable globals cannot be imported"); } ++num_imported_globals_; ++current_global_index_; break; + } } } @@ -866,31 +863,31 @@ Result Validator::CheckModule(const Module* module) { current_except_index_ = 0; for (const ModuleField& field : module->fields) { - switch (field.type) { + switch (field.type()) { case ModuleFieldType::Except: ++current_except_index_; - CheckExcept(&field.loc, cast<ExceptionModuleField>(&field)->except); + CheckExcept(&field.loc, &cast<ExceptionModuleField>(&field)->except); break; case ModuleFieldType::Func: - CheckFunc(&field.loc, cast<FuncModuleField>(&field)->func); + CheckFunc(&field.loc, &cast<FuncModuleField>(&field)->func); break; case ModuleFieldType::Global: - CheckGlobal(&field.loc, cast<GlobalModuleField>(&field)->global); + CheckGlobal(&field.loc, &cast<GlobalModuleField>(&field)->global); current_global_index_++; break; case ModuleFieldType::Import: - CheckImport(&field.loc, cast<ImportModuleField>(&field)->import); + CheckImport(&field.loc, cast<ImportModuleField>(&field)->import.get()); break; case ModuleFieldType::Export: - CheckExport(&field.loc, cast<ExportModuleField>(&field)->export_); + CheckExport(&field.loc, &cast<ExportModuleField>(&field)->export_); break; case ModuleFieldType::Table: - CheckTable(&field.loc, cast<TableModuleField>(&field)->table); + CheckTable(&field.loc, &cast<TableModuleField>(&field)->table); current_table_index_++; break; @@ -899,7 +896,7 @@ Result Validator::CheckModule(const Module* module) { break; case ModuleFieldType::Memory: - CheckMemory(&field.loc, cast<MemoryModuleField>(&field)->memory); + CheckMemory(&field.loc, &cast<MemoryModuleField>(&field)->memory); current_memory_index_++; break; @@ -942,8 +939,7 @@ Result Validator::CheckModule(const Module* module) { // Returns the result type of the invoked function, checked by the caller; // returning nullptr means that another error occured first, so the result type // should be ignored. -const TypeVector* Validator::CheckInvoke(const Action* action) { - const ActionInvoke* invoke = action->invoke; +const TypeVector* Validator::CheckInvoke(const InvokeAction* action) { const Module* module = script_->GetModule(action->module_var); if (!module) { PrintError(&action->loc, "unknown module"); @@ -963,7 +959,7 @@ const TypeVector* Validator::CheckInvoke(const Action* action) { return nullptr; } - size_t actual_args = invoke->args.size(); + size_t actual_args = action->args.size(); size_t expected_args = func->GetNumParams(); if (expected_args != actual_args) { PrintError(&action->loc, "too %s parameters to function. got %" PRIzd @@ -973,7 +969,7 @@ const TypeVector* Validator::CheckInvoke(const Action* action) { return nullptr; } for (size_t i = 0; i < actual_args; ++i) { - const Const* const_ = &invoke->args[i]; + const Const* const_ = &action->args[i]; CheckTypeIndex(&const_->loc, const_->type, func->GetParamType(i), "invoke", i, "argument"); } @@ -981,7 +977,7 @@ const TypeVector* Validator::CheckInvoke(const Action* action) { return &func->decl.sig.result_types; } -Result Validator::CheckGet(const Action* action, Type* out_type) { +Result Validator::CheckGet(const GetAction* action, Type* out_type) { const Module* module = script_->GetModule(action->module_var); if (!module) { PrintError(&action->loc, "unknown module"); @@ -1035,15 +1031,15 @@ Validator::ActionResult Validator::CheckAction(const Action* action) { ActionResult result; ZeroMemory(result); - switch (action->type) { + switch (action->type()) { case ActionType::Invoke: - result.types = CheckInvoke(action); + result.types = CheckInvoke(cast<InvokeAction>(action)); result.kind = result.types ? ActionResult::Kind::Types : ActionResult::Kind::Error; break; case ActionType::Get: - if (Succeeded(CheckGet(action, &result.type))) + if (Succeeded(CheckGet(cast<GetAction>(action), &result.type))) result.kind = ActionResult::Kind::Type; else result.kind = ActionResult::Kind::Error; @@ -1078,12 +1074,12 @@ void Validator::CheckAssertReturnNanCommand(const Action* action) { void Validator::CheckCommand(const Command* command) { switch (command->type) { case CommandType::Module: - CheckModule(cast<ModuleCommand>(command)->module); + CheckModule(&cast<ModuleCommand>(command)->module); break; case CommandType::Action: // Ignore result type. - CheckAction(cast<ActionCommand>(command)->action); + CheckAction(cast<ActionCommand>(command)->action.get()); break; case CommandType::Register: @@ -1096,17 +1092,17 @@ void Validator::CheckCommand(const Command* command) { case CommandType::AssertReturn: { auto* assert_return_command = cast<AssertReturnCommand>(command); - const Action* action = assert_return_command->action; + const Action* action = assert_return_command->action.get(); ActionResult result = CheckAction(action); switch (result.kind) { case ActionResult::Kind::Types: CheckConstTypes(&action->loc, *result.types, - *assert_return_command->expected, "action"); + assert_return_command->expected, "action"); break; case ActionResult::Kind::Type: CheckConstType(&action->loc, result.type, - *assert_return_command->expected, "action"); + assert_return_command->expected, "action"); break; case ActionResult::Kind::Error: @@ -1118,21 +1114,21 @@ void Validator::CheckCommand(const Command* command) { case CommandType::AssertReturnCanonicalNan: CheckAssertReturnNanCommand( - cast<AssertReturnCanonicalNanCommand>(command)->action); + cast<AssertReturnCanonicalNanCommand>(command)->action.get()); break; case CommandType::AssertReturnArithmeticNan: CheckAssertReturnNanCommand( - cast<AssertReturnArithmeticNanCommand>(command)->action); + cast<AssertReturnArithmeticNanCommand>(command)->action.get()); break; case CommandType::AssertTrap: // ignore result type. - CheckAction(cast<AssertTrapCommand>(command)->action); + CheckAction(cast<AssertTrapCommand>(command)->action.get()); break; case CommandType::AssertExhaustion: // ignore result type. - CheckAction(cast<AssertExhaustionCommand>(command)->action); + CheckAction(cast<AssertExhaustionCommand>(command)->action.get()); break; } } diff --git a/src/wasm-link.h b/src/wasm-link.h index c1509802..beec2031 100644 --- a/src/wasm-link.h +++ b/src/wasm-link.h @@ -81,7 +81,7 @@ struct Section { /* DATA section data */ std::vector<DataSegment>* data_segments; /* MEMORY section data */ - Limits memory_limits; + uint64_t initial; } data; /* The offset at which this section appears within the combined output diff --git a/src/wast-parser.cc b/src/wast-parser.cc index 139f5a7a..acfa4548 100644 --- a/src/wast-parser.cc +++ b/src/wast-parser.cc @@ -101,7 +101,7 @@ typedef std::vector<std::string> TextVector; template <typename OutputIter> void RemoveEscapes(const TextVector& texts, OutputIter out) { - for (const std::string& text: texts) + for (const std::string& text : texts) RemoveEscapes(text, out); } @@ -252,12 +252,12 @@ bool IsEmptySignature(const FuncSignature* sig) { void ResolveFuncTypes(Module* module) { for (ModuleField& field : module->fields) { Func* func = nullptr; - if (field.type == ModuleFieldType::Func) { - func = dyn_cast<FuncModuleField>(&field)->func; - } else if (field.type == ModuleFieldType::Import) { - Import* import = dyn_cast<ImportModuleField>(&field)->import; - if (import->kind == ExternalKind::Func) { - func = import->func; + if (auto* func_field = dyn_cast<FuncModuleField>(&field)) { + func = &func_field->func; + } else if (auto* import_field = dyn_cast<ImportModuleField>(&field)) { + auto&& import = import_field->import; + if (auto* func_import = dyn_cast<FuncImport>(import.get())) { + func = &func_import->func; } else { continue; } @@ -278,9 +278,9 @@ void ResolveFuncTypes(Module* module) { if (!func->decl.has_func_type) { Index func_type_index = module->GetFuncTypeIndex(func->decl.sig); if (func_type_index == kInvalidIndex) { - auto func_type = new FuncType(); - func_type->sig = func->decl.sig; - module->AppendField(new FuncTypeModuleField(func_type, field.loc)); + auto* func_type_field = new FuncTypeModuleField(field.loc); + func_type_field->func_type.sig = func->decl.sig; + module->AppendField(func_type_field); } } } @@ -291,9 +291,9 @@ void AppendInlineExportFields(Module* module, Index index) { Location last_field_loc = module->fields.back().loc; - for (const ModuleField& field: *fields) { + for (ModuleField& field : *fields) { auto* export_field = cast<ExportModuleField>(&field); - export_field->export_->var = Var(index, last_field_loc); + export_field->export_.var = Var(index, last_field_loc); } module->AppendFields(fields); @@ -644,10 +644,10 @@ Result WastParser::ParseScript(Script* script) { // the parsing structure more regular. if (IsModuleField(PeekPair())) { // Parse an inline module (i.e. one with no surrounding (module)). - auto module = make_unique<Module>(); - module->loc = GetLocation(); - CHECK_RESULT(ParseModuleFieldList(module.get())); - script->commands.emplace_back(make_unique<ModuleCommand>(module.release())); + auto command = MakeUnique<ModuleCommand>(); + command->module.loc = GetLocation(); + CHECK_RESULT(ParseModuleFieldList(&command->module)); + script->commands.emplace_back(std::move(command)); } else if (IsCommand(PeekPair())) { CHECK_RESULT(ParseCommandList(&script->commands)); } else { @@ -695,13 +695,13 @@ Result WastParser::ParseDataModuleField(Module* module) { WABT_TRACE(ParseDataModuleField); EXPECT(Lpar); auto loc = GetLocation(); + auto field = MakeUnique<DataSegmentModuleField>(loc); EXPECT(Data); - auto data_segment = make_unique<DataSegment>(); - ParseVarOpt(&data_segment->memory_var, Var(0, loc)); - CHECK_RESULT(ParseOffsetExpr(&data_segment->offset)); - ParseTextListOpt(&data_segment->data); + ParseVarOpt(&field->data_segment.memory_var, Var(0, loc)); + CHECK_RESULT(ParseOffsetExpr(&field->data_segment.offset)); + ParseTextListOpt(&field->data_segment.data); EXPECT(Rpar); - module->AppendField(new DataSegmentModuleField(data_segment.release(), loc)); + module->AppendField(field.release()); return Result::Ok; } @@ -709,39 +709,37 @@ Result WastParser::ParseElemModuleField(Module* module) { WABT_TRACE(ParseElemModuleField); EXPECT(Lpar); auto loc = GetLocation(); + auto field = MakeUnique<ElemSegmentModuleField>(loc); EXPECT(Elem); - auto elem_segment = make_unique<ElemSegment>(); - ParseVarOpt(&elem_segment->table_var, Var(0, loc)); - CHECK_RESULT(ParseOffsetExpr(&elem_segment->offset)); - ParseVarListOpt(&elem_segment->vars); + ParseVarOpt(&field->elem_segment.table_var, Var(0, loc)); + CHECK_RESULT(ParseOffsetExpr(&field->elem_segment.offset)); + ParseVarListOpt(&field->elem_segment.vars); EXPECT(Rpar); - module->AppendField(new ElemSegmentModuleField(elem_segment.release(), loc)); + module->AppendField(field.release()); return Result::Ok; } Result WastParser::ParseExceptModuleField(Module* module) { WABT_TRACE(ParseExceptModuleField); EXPECT(Lpar); - auto loc = GetLocation(); + auto field = MakeUnique<ExceptionModuleField>(GetLocation()); EXPECT(Except); - auto exception = make_unique<Exception>(); - ParseBindVarOpt(&exception->name); - ParseValueTypeList(&exception->sig); + ParseBindVarOpt(&field->except.name); + ParseValueTypeList(&field->except.sig); EXPECT(Rpar); - module->AppendField(new ExceptionModuleField(exception.release(), loc)); + module->AppendField(field.release()); return Result::Ok; } Result WastParser::ParseExportModuleField(Module* module) { WABT_TRACE(ParseExportModuleField); EXPECT(Lpar); - auto loc = GetLocation(); + auto field = MakeUnique<ExportModuleField>(GetLocation()); EXPECT(Export); - auto export_ = make_unique<Export>(); - CHECK_RESULT(ParseQuotedText(&export_->name)); - CHECK_RESULT(ParseExportDesc(export_.get())); + CHECK_RESULT(ParseQuotedText(&field->export_.name)); + CHECK_RESULT(ParseExportDesc(&field->export_)); EXPECT(Rpar); - module->AppendField(new ExportModuleField(export_.release(), loc)); + module->AppendField(field.release()); return Result::Ok; } @@ -750,31 +748,32 @@ Result WastParser::ParseFuncModuleField(Module* module) { EXPECT(Lpar); auto loc = GetLocation(); EXPECT(Func); - auto func = make_unique<Func>(); - ParseBindVarOpt(&func->name); + std::string name; + ParseBindVarOpt(&name); ModuleFieldList export_fields; CHECK_RESULT(ParseInlineExports(&export_fields, ExternalKind::Func)); if (PeekMatchLpar(TokenType::Import)) { CheckImportOrdering(module); - auto import_loc = GetLocation(); - auto import = make_unique<Import>(); - import->kind = ExternalKind::Func; - import->func = func.release(); + auto import = MakeUnique<FuncImport>(name); + auto&& func = import->func; CHECK_RESULT(ParseInlineImport(import.get())); - CHECK_RESULT(ParseTypeUseOpt(&import->func->decl)); - CHECK_RESULT(ParseFuncSignature(&import->func->decl.sig, - &import->func->param_bindings)); + CHECK_RESULT(ParseTypeUseOpt(&func.decl)); + CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.param_bindings)); CHECK_RESULT(ErrorIfLpar({"type", "param", "result"})); - module->AppendField(new ImportModuleField(import.release(), import_loc)); + auto field = + MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->AppendField(field.release()); } else { - CHECK_RESULT(ParseTypeUseOpt(&func->decl)); - CHECK_RESULT(ParseFuncSignature(&func->decl.sig, &func->param_bindings)); - CHECK_RESULT(ParseBoundValueTypeList(TokenType::Local, &func->local_types, - &func->local_bindings)); - CHECK_RESULT(ParseTerminatingInstrList(&func->exprs)); - module->AppendField(new FuncModuleField(func.release(), loc)); + auto field = MakeUnique<FuncModuleField>(loc, name); + auto&& func = field->func; + CHECK_RESULT(ParseTypeUseOpt(&func.decl)); + CHECK_RESULT(ParseFuncSignature(&func.decl.sig, &func.param_bindings)); + CHECK_RESULT(ParseBoundValueTypeList(TokenType::Local, &func.local_types, + &func.local_bindings)); + CHECK_RESULT(ParseTerminatingInstrList(&func.exprs)); + module->AppendField(field.release()); } AppendInlineExportFields(module, &export_fields, module->funcs.size() - 1); @@ -786,18 +785,17 @@ Result WastParser::ParseFuncModuleField(Module* module) { Result WastParser::ParseTypeModuleField(Module* module) { WABT_TRACE(ParseTypeModuleField); EXPECT(Lpar); - auto loc = GetLocation(); + auto field = MakeUnique<FuncTypeModuleField>(GetLocation()); EXPECT(Type); - auto func_type = make_unique<FuncType>(); - ParseBindVarOpt(&func_type->name); + ParseBindVarOpt(&field->func_type.name); EXPECT(Lpar); EXPECT(Func); BindingHash bindings; - CHECK_RESULT(ParseFuncSignature(&func_type->sig, &bindings)); + CHECK_RESULT(ParseFuncSignature(&field->func_type.sig, &bindings)); CHECK_RESULT(ErrorIfLpar({"param", "result"})); EXPECT(Rpar); EXPECT(Rpar); - module->AppendField(new FuncTypeModuleField(func_type.release(), loc)); + module->AppendField(field.release()); return Result::Ok; } @@ -806,25 +804,25 @@ Result WastParser::ParseGlobalModuleField(Module* module) { EXPECT(Lpar); auto loc = GetLocation(); EXPECT(Global); - auto global = make_unique<Global>(); - ParseBindVarOpt(&global->name); + std::string name; + ParseBindVarOpt(&name); ModuleFieldList export_fields; CHECK_RESULT(ParseInlineExports(&export_fields, ExternalKind::Global)); if (PeekMatchLpar(TokenType::Import)) { CheckImportOrdering(module); - auto import_loc = GetLocation(); - auto import = make_unique<Import>(); - import->kind = ExternalKind::Global; - import->global = global.release(); + auto import = MakeUnique<GlobalImport>(name); CHECK_RESULT(ParseInlineImport(import.get())); - CHECK_RESULT(ParseGlobalType(import->global)); - module->AppendField(new ImportModuleField(import.release(), import_loc)); + CHECK_RESULT(ParseGlobalType(&import->global)); + auto field = + MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->AppendField(field.release()); } else { - CHECK_RESULT(ParseGlobalType(global.get())); - CHECK_RESULT(ParseTerminatingInstrList(&global->init_expr)); - module->AppendField(new GlobalModuleField(global.release(), loc)); + auto field = MakeUnique<GlobalModuleField>(loc, name); + CHECK_RESULT(ParseGlobalType(&field->global)); + CHECK_RESULT(ParseTerminatingInstrList(&field->global.init_expr)); + module->AppendField(field.release()); } AppendInlineExportFields(module, &export_fields, module->globals.size() - 1); @@ -839,70 +837,83 @@ Result WastParser::ParseImportModuleField(Module* module) { auto loc = GetLocation(); CheckImportOrdering(module); EXPECT(Import); - auto import = make_unique<Import>(); - CHECK_RESULT(ParseQuotedText(&import->module_name)); - CHECK_RESULT(ParseQuotedText(&import->field_name)); + std::string module_name; + std::string field_name; + CHECK_RESULT(ParseQuotedText(&module_name)); + CHECK_RESULT(ParseQuotedText(&field_name)); EXPECT(Lpar); + + std::unique_ptr<ImportModuleField> field; + std::string name; + switch (Peek()) { - case TokenType::Func: + case TokenType::Func: { Consume(); - import->kind = ExternalKind::Func; - import->func = new Func(); - ParseBindVarOpt(&import->func->name); + ParseBindVarOpt(&name); + auto import = MakeUnique<FuncImport>(name); if (PeekMatchLpar(TokenType::Type)) { - import->func->decl.has_func_type = true; - CHECK_RESULT(ParseTypeUseOpt(&import->func->decl)); + import->func.decl.has_func_type = true; + CHECK_RESULT(ParseTypeUseOpt(&import->func.decl)); EXPECT(Rpar); } else { - CHECK_RESULT(ParseFuncSignature(&import->func->decl.sig, - &import->func->param_bindings)); + CHECK_RESULT(ParseFuncSignature(&import->func.decl.sig, + &import->func.param_bindings)); CHECK_RESULT(ErrorIfLpar({"param", "result"})); EXPECT(Rpar); } + field = MakeUnique<ImportModuleField>(std::move(import), loc); break; + } - case TokenType::Table: + case TokenType::Table: { Consume(); - import->kind = ExternalKind::Table; - import->table = new Table(); - ParseBindVarOpt(&import->table->name); - CHECK_RESULT(ParseLimits(&import->table->elem_limits)); + ParseBindVarOpt(&name); + auto import = MakeUnique<TableImport>(name); + CHECK_RESULT(ParseLimits(&import->table.elem_limits)); EXPECT(Anyfunc); EXPECT(Rpar); + field = MakeUnique<ImportModuleField>(std::move(import), loc); break; + } - case TokenType::Memory: + case TokenType::Memory: { Consume(); - import->kind = ExternalKind::Memory; - import->memory = new Memory(); - ParseBindVarOpt(&import->memory->name); - CHECK_RESULT(ParseLimits(&import->memory->page_limits)); + ParseBindVarOpt(&name); + auto import = MakeUnique<MemoryImport>(name); + CHECK_RESULT(ParseLimits(&import->memory.page_limits)); EXPECT(Rpar); + field = MakeUnique<ImportModuleField>(std::move(import), loc); break; + } - case TokenType::Global: + case TokenType::Global: { Consume(); - import->kind = ExternalKind::Global; - import->global = new Global(); - ParseBindVarOpt(&import->global->name); - CHECK_RESULT(ParseGlobalType(import->global)); + ParseBindVarOpt(&name); + auto import = MakeUnique<GlobalImport>(name); + CHECK_RESULT(ParseGlobalType(&import->global)); EXPECT(Rpar); + field = MakeUnique<ImportModuleField>(std::move(import), loc); break; + } - case TokenType::Except: + case TokenType::Except: { Consume(); - import->kind = ExternalKind::Except; - import->except = new Exception(); - ParseBindVarOpt(&import->except->name); - ParseValueTypeList(&import->except->sig); + ParseBindVarOpt(&name); + auto import = MakeUnique<ExceptionImport>(name); + ParseValueTypeList(&import->except.sig); EXPECT(Rpar); + field = MakeUnique<ImportModuleField>(std::move(import), loc); break; + } default: return ErrorExpected({"an external kind"}); } - module->AppendField(new ImportModuleField(import.release(), loc)); + field->import->module_name = module_name; + field->import->field_name = field_name; + + module->AppendField(field.release()); EXPECT(Rpar); return Result::Ok; } @@ -912,41 +923,42 @@ Result WastParser::ParseMemoryModuleField(Module* module) { EXPECT(Lpar); auto loc = GetLocation(); EXPECT(Memory); - auto memory = make_unique<Memory>(); - ParseBindVarOpt(&memory->name); + std::string name; + ParseBindVarOpt(&name); ModuleFieldList export_fields; CHECK_RESULT(ParseInlineExports(&export_fields, ExternalKind::Memory)); if (PeekMatchLpar(TokenType::Import)) { CheckImportOrdering(module); - auto import_loc = GetLocation(); - auto import = make_unique<Import>(); - import->kind = ExternalKind::Memory; - import->memory = memory.release(); + auto import = MakeUnique<MemoryImport>(name); CHECK_RESULT(ParseInlineImport(import.get())); - CHECK_RESULT(ParseLimits(&import->memory->page_limits)); - module->AppendField(new ImportModuleField(import.release(), import_loc)); + CHECK_RESULT(ParseLimits(&import->memory.page_limits)); + auto field = + MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->AppendField(field.release()); } else if (MatchLpar(TokenType::Data)) { - auto data_segment = make_unique<DataSegment>(); - data_segment->memory_var = Var(module->memories.size()); - data_segment->offset.push_back(new ConstExpr(Const(Const::I32(), 0))); - data_segment->offset.back().loc = loc; - ParseTextListOpt(&data_segment->data); + auto data_segment_field = MakeUnique<DataSegmentModuleField>(loc); + auto&& data_segment = data_segment_field->data_segment; + data_segment.memory_var = Var(module->memories.size()); + data_segment.offset.push_back(new ConstExpr(Const::I32(0))); + data_segment.offset.back().loc = loc; + ParseTextListOpt(&data_segment.data); EXPECT(Rpar); - uint32_t byte_size = WABT_ALIGN_UP_TO_PAGE(data_segment->data.size()); + auto memory_field = MakeUnique<MemoryModuleField>(loc, name); + uint32_t byte_size = WABT_ALIGN_UP_TO_PAGE(data_segment.data.size()); uint32_t page_size = WABT_BYTES_TO_PAGES(byte_size); - memory->page_limits.initial = page_size; - memory->page_limits.max = page_size; - memory->page_limits.has_max = true; + memory_field->memory.page_limits.initial = page_size; + memory_field->memory.page_limits.max = page_size; + memory_field->memory.page_limits.has_max = true; - module->AppendField(new MemoryModuleField(memory.release(), loc)); - module->AppendField( - new DataSegmentModuleField(data_segment.release(), loc)); + module->AppendField(memory_field.release()); + module->AppendField(data_segment_field.release()); } else { - CHECK_RESULT(ParseLimits(&memory->page_limits)); - module->AppendField(new MemoryModuleField(memory.release(), loc)); + auto field = MakeUnique<MemoryModuleField>(loc, name); + CHECK_RESULT(ParseLimits(&field->memory.page_limits)); + module->AppendField(field.release()); } AppendInlineExportFields(module, &export_fields, module->memories.size() - 1); @@ -972,43 +984,44 @@ Result WastParser::ParseTableModuleField(Module* module) { EXPECT(Lpar); auto loc = GetLocation(); EXPECT(Table); - auto table = make_unique<Table>(); - ParseBindVarOpt(&table->name); + std::string name; + ParseBindVarOpt(&name); ModuleFieldList export_fields; CHECK_RESULT(ParseInlineExports(&export_fields, ExternalKind::Table)); if (PeekMatchLpar(TokenType::Import)) { CheckImportOrdering(module); - auto import_loc = GetLocation(); - auto import = make_unique<Import>(); - import->kind = ExternalKind::Table; - import->table = table.release(); + auto import = MakeUnique<TableImport>(name); CHECK_RESULT(ParseInlineImport(import.get())); - CHECK_RESULT(ParseLimits(&import->table->elem_limits)); + CHECK_RESULT(ParseLimits(&import->table.elem_limits)); EXPECT(Anyfunc); - module->AppendField(new ImportModuleField(import.release(), import_loc)); + auto field = + MakeUnique<ImportModuleField>(std::move(import), GetLocation()); + module->AppendField(field.release()); } else if (Match(TokenType::Anyfunc)) { EXPECT(Lpar); EXPECT(Elem); - auto elem_segment = make_unique<ElemSegment>(); - elem_segment->table_var = Var(module->tables.size()); - elem_segment->offset.push_back(new ConstExpr(Const(Const::I32(), 0))); - elem_segment->offset.back().loc = loc; - CHECK_RESULT(ParseVarList(&elem_segment->vars)); + auto elem_segment_field = MakeUnique<ElemSegmentModuleField>(loc); + auto&& elem_segment = elem_segment_field->elem_segment; + elem_segment.table_var = Var(module->tables.size()); + elem_segment.offset.push_back(new ConstExpr(Const::I32(0))); + elem_segment.offset.back().loc = loc; + CHECK_RESULT(ParseVarList(&elem_segment.vars)); EXPECT(Rpar); - table->elem_limits.initial = elem_segment->vars.size(); - table->elem_limits.max = elem_segment->vars.size(); - table->elem_limits.has_max = true; - module->AppendField(new TableModuleField(table.release(), loc)); - module->AppendField( - new ElemSegmentModuleField(elem_segment.release(), loc)); + auto table_field = MakeUnique<TableModuleField>(loc, name); + table_field->table.elem_limits.initial = elem_segment.vars.size(); + table_field->table.elem_limits.max = elem_segment.vars.size(); + table_field->table.elem_limits.has_max = true; + module->AppendField(table_field.release()); + module->AppendField(elem_segment_field.release()); } else { - CHECK_RESULT(ParseLimits(&table->elem_limits)); + auto field = MakeUnique<TableModuleField>(loc, name); + CHECK_RESULT(ParseLimits(&field->table.elem_limits)); EXPECT(Anyfunc); - module->AppendField(new TableModuleField(table.release(), loc)); + module->AppendField(field.release()); } AppendInlineExportFields(module, &export_fields, module->tables.size() - 1); @@ -1040,13 +1053,12 @@ Result WastParser::ParseInlineExports(ModuleFieldList* fields, WABT_TRACE(ParseInlineExports); while (PeekMatchLpar(TokenType::Export)) { EXPECT(Lpar); - auto loc = GetLocation(); + auto field = MakeUnique<ExportModuleField>(GetLocation()); + field->export_.kind = kind; EXPECT(Export); - auto export_ = make_unique<Export>(); - export_->kind = kind; - CHECK_RESULT(ParseQuotedText(&export_->name)); + CHECK_RESULT(ParseQuotedText(&field->export_.name)); EXPECT(Rpar); - fields->push_back(new ExportModuleField(export_.release(), loc)); + fields->push_back(field.release()); } return Result::Ok; } @@ -1064,7 +1076,7 @@ Result WastParser::ParseInlineImport(Import* import) { Result WastParser::ParseTypeUseOpt(FuncDeclaration* decl) { WABT_TRACE(ParseTypeUseOpt); if (MatchLpar(TokenType::Type)) { - decl->has_func_type = true;; + decl->has_func_type = true; CHECK_RESULT(ParseVar(&decl->type_var)); EXPECT(Rpar); } else { @@ -1200,11 +1212,11 @@ Result WastParser::ParsePlainInstr(std::unique_ptr<Expr>* out_expr) { case TokenType::BrTable: { Consume(); - auto var_list = make_unique<VarVector>(); - CHECK_RESULT(ParseVarList(var_list.get())); - Var var = var_list->back(); - var_list->pop_back(); - out_expr->reset(new BrTableExpr(var_list.release(), var, loc)); + auto expr = MakeUnique<BrTableExpr>(loc); + CHECK_RESULT(ParseVarList(&expr->targets)); + expr->default_target = expr->targets.back(); + expr->targets.pop_back(); + *out_expr = std::move(expr); break; } @@ -1401,53 +1413,51 @@ Result WastParser::ParseBlockInstr(std::unique_ptr<Expr>* out_expr) { switch (Peek()) { case TokenType::Block: { Consume(); - auto block = make_unique<Block>(); - CHECK_RESULT(ParseLabelOpt(&block->label)); - CHECK_RESULT(ParseBlock(block.get())); + auto expr = MakeUnique<BlockExpr>(loc); + CHECK_RESULT(ParseLabelOpt(&expr->block.label)); + CHECK_RESULT(ParseBlock(&expr->block)); EXPECT(End); - CHECK_RESULT(ParseEndLabelOpt(block->label)); - out_expr->reset(new BlockExpr(block.release(), loc)); + CHECK_RESULT(ParseEndLabelOpt(expr->block.label)); + *out_expr = std::move(expr); break; } case TokenType::Loop: { Consume(); - auto block = make_unique<Block>(); - CHECK_RESULT(ParseLabelOpt(&block->label)); - CHECK_RESULT(ParseBlock(block.get())); + auto expr = MakeUnique<LoopExpr>(loc); + CHECK_RESULT(ParseLabelOpt(&expr->block.label)); + CHECK_RESULT(ParseBlock(&expr->block)); EXPECT(End); - CHECK_RESULT(ParseEndLabelOpt(block->label)); - out_expr->reset(new LoopExpr(block.release(), loc)); + CHECK_RESULT(ParseEndLabelOpt(expr->block.label)); + *out_expr = std::move(expr); break; } case TokenType::If: { Consume(); - auto true_ = make_unique<Block>(); - ExprList false_; - CHECK_RESULT(ParseLabelOpt(&true_->label)); - CHECK_RESULT(ParseBlock(true_.get())); + auto expr = MakeUnique<IfExpr>(loc); + CHECK_RESULT(ParseLabelOpt(&expr->true_.label)); + CHECK_RESULT(ParseBlock(&expr->true_)); if (Match(TokenType::Else)) { - CHECK_RESULT(ParseEndLabelOpt(true_->label)); - CHECK_RESULT(ParseTerminatingInstrList(&false_)); + CHECK_RESULT(ParseEndLabelOpt(expr->true_.label)); + CHECK_RESULT(ParseTerminatingInstrList(&expr->false_)); } EXPECT(End); - CHECK_RESULT(ParseEndLabelOpt(true_->label)); - out_expr->reset(new IfExpr(true_.release(), std::move(false_), loc)); + CHECK_RESULT(ParseEndLabelOpt(expr->true_.label)); + *out_expr = std::move(expr); break; } case TokenType::Try: { ErrorUnlessOpcodeEnabled(Consume()); - auto expr = make_unique<TryExpr>(loc); - expr->block = new Block(); + auto expr = MakeUnique<TryExpr>(loc); CatchVector catches; - CHECK_RESULT(ParseLabelOpt(&expr->block->label)); - CHECK_RESULT(ParseBlock(expr->block)); + CHECK_RESULT(ParseLabelOpt(&expr->block.label)); + CHECK_RESULT(ParseBlock(&expr->block)); CHECK_RESULT(ParseCatchInstrList(&expr->catches)); CHECK_RESULT(ErrorIfLpar({"a catch expr"})); EXPECT(End); - CHECK_RESULT(ParseEndLabelOpt(expr->block->label)); + CHECK_RESULT(ParseEndLabelOpt(expr->block.label)); *out_expr = std::move(expr); break; } @@ -1526,31 +1536,30 @@ Result WastParser::ParseExpr(ExprList* exprs) { case TokenType::Block: { Consume(); Consume(); - auto block = make_unique<Block>(); - CHECK_RESULT(ParseLabelOpt(&block->label)); - CHECK_RESULT(ParseBlock(block.get())); - exprs->push_back(new BlockExpr(block.release(), loc)); + auto expr = MakeUnique<BlockExpr>(loc); + CHECK_RESULT(ParseLabelOpt(&expr->block.label)); + CHECK_RESULT(ParseBlock(&expr->block)); + exprs->push_back(expr.release()); break; } case TokenType::Loop: { Consume(); Consume(); - auto block = make_unique<Block>(); - CHECK_RESULT(ParseLabelOpt(&block->label)); - CHECK_RESULT(ParseBlock(block.get())); - exprs->push_back(new LoopExpr(block.release(), loc)); + auto expr = MakeUnique<LoopExpr>(); + CHECK_RESULT(ParseLabelOpt(&expr->block.label)); + CHECK_RESULT(ParseBlock(&expr->block)); + exprs->push_back(expr.release()); break; } case TokenType::If: { Consume(); Consume(); - auto true_ = make_unique<Block>(); - ExprList false_; + auto expr = MakeUnique<IfExpr>(loc); - CHECK_RESULT(ParseLabelOpt(&true_->label)); - CHECK_RESULT(ParseResultList(&true_->sig)); + CHECK_RESULT(ParseLabelOpt(&expr->true_.label)); + CHECK_RESULT(ParseResultList(&expr->true_.sig)); if (PeekMatchExpr()) { ExprList cond; @@ -1559,26 +1568,26 @@ Result WastParser::ParseExpr(ExprList* exprs) { } if (MatchLpar(TokenType::Then)) { - CHECK_RESULT(ParseTerminatingInstrList(&true_->exprs)); + CHECK_RESULT(ParseTerminatingInstrList(&expr->true_.exprs)); EXPECT(Rpar); if (MatchLpar(TokenType::Else)) { - CHECK_RESULT(ParseTerminatingInstrList(&false_)); + CHECK_RESULT(ParseTerminatingInstrList(&expr->false_)); EXPECT(Rpar); } else if (PeekMatchExpr()) { - CHECK_RESULT(ParseExpr(&false_)); + CHECK_RESULT(ParseExpr(&expr->false_)); } } else if (PeekMatchExpr()) { - CHECK_RESULT(ParseExpr(&true_->exprs)); + CHECK_RESULT(ParseExpr(&expr->true_.exprs)); if (PeekMatchExpr()) { - CHECK_RESULT(ParseExpr(&false_)); + CHECK_RESULT(ParseExpr(&expr->false_)); } } else { ConsumeIfLpar(); return ErrorExpected({"then block"}, "(then ...)"); } - exprs->push_back(new IfExpr(true_.release(), std::move(false_), loc)); + exprs->push_back(expr.release()); break; } @@ -1586,16 +1595,14 @@ Result WastParser::ParseExpr(ExprList* exprs) { Consume(); ErrorUnlessOpcodeEnabled(Consume()); - auto block = make_unique<Block>(); - CHECK_RESULT(ParseLabelOpt(&block->label)); - CHECK_RESULT(ParseResultList(&block->sig)); - CHECK_RESULT(ParseInstrList(&block->exprs)); - auto try_ = make_unique<TryExpr>(loc); - try_->block = block.release(); - CHECK_RESULT(ParseCatchExprList(&try_->catches)); + auto expr = MakeUnique<TryExpr>(loc); + CHECK_RESULT(ParseLabelOpt(&expr->block.label)); + CHECK_RESULT(ParseResultList(&expr->block.sig)); + CHECK_RESULT(ParseInstrList(&expr->block.exprs)); + CHECK_RESULT(ParseCatchExprList(&expr->catches)); CHECK_RESULT(ErrorIfLpar({"a catch expr"})); - exprs->push_back(try_.release()); + exprs->push_back(expr.release()); break; } @@ -1612,14 +1619,13 @@ Result WastParser::ParseExpr(ExprList* exprs) { Result WastParser::ParseCatchInstrList(CatchVector* catches) { WABT_TRACE(ParseCatchInstrList); while (IsCatch(Peek())) { - auto catch_ = make_unique<Catch>(); - catch_->loc = GetLocation(); + Catch catch_(GetLocation()); if (Consume().token_type == TokenType::Catch) - CHECK_RESULT(ParseVar(&catch_->var)); + CHECK_RESULT(ParseVar(&catch_.var)); - CHECK_RESULT(ParseInstrList(&catch_->exprs)); - catches->push_back(catch_.release()); + CHECK_RESULT(ParseInstrList(&catch_.exprs)); + catches->push_back(std::move(catch_)); } return Result::Ok; @@ -1629,15 +1635,14 @@ Result WastParser::ParseCatchExprList(CatchVector* catches) { WABT_TRACE(ParseCatchExprList); while (PeekMatch(TokenType::Lpar) && IsCatch(Peek(1))) { Consume(); - auto catch_ = make_unique<Catch>(); - catch_->loc = GetLocation(); + Catch catch_(GetLocation()); if (Consume().token_type == TokenType::Catch) - CHECK_RESULT(ParseVar(&catch_->var)); + CHECK_RESULT(ParseVar(&catch_.var)); - CHECK_RESULT(ParseTerminatingInstrList(&catch_->exprs)); + CHECK_RESULT(ParseTerminatingInstrList(&catch_.exprs)); EXPECT(Rpar); - catches->push_back(catch_.release()); + catches->push_back(std::move(catch_)); } return Result::Ok; @@ -1735,13 +1740,11 @@ Result WastParser::ParseAssertReturnCommand(CommandPtr* out_command) { WABT_TRACE(ParseAssertReturnCommand); EXPECT(Lpar); EXPECT(AssertReturn); - auto action = make_unique<Action>(); - auto consts = make_unique<ConstVector>(); - CHECK_RESULT(ParseAction(action.get())); - CHECK_RESULT(ParseConstList(consts.get())); + auto command = MakeUnique<AssertReturnCommand>(); + CHECK_RESULT(ParseAction(&command->action)); + CHECK_RESULT(ParseConstList(&command->expected)); EXPECT(Rpar); - out_command->reset( - new AssertReturnCommand(action.release(), consts.release())); + *out_command = std::move(command); return Result::Ok; } @@ -1764,17 +1767,15 @@ Result WastParser::ParseAssertTrapCommand(CommandPtr* out_command) { EXPECT(Lpar); EXPECT(AssertTrap); if (PeekMatchLpar(TokenType::Module)) { - std::unique_ptr<ScriptModule> module; - std::string text; - CHECK_RESULT(ParseScriptModule(&module)); - CHECK_RESULT(ParseQuotedText(&text)); - out_command->reset(new AssertUninstantiableCommand(module.release(), text)); + auto command = MakeUnique<AssertUninstantiableCommand>(); + CHECK_RESULT(ParseScriptModule(&command->module)); + CHECK_RESULT(ParseQuotedText(&command->text)); + *out_command = std::move(command); } else { - auto action = make_unique<Action>(); - std::string text; - CHECK_RESULT(ParseAction(action.get())); - CHECK_RESULT(ParseQuotedText(&text)); - out_command->reset(new AssertTrapCommand(action.release(), text)); + auto command = MakeUnique<AssertTrapCommand>(); + CHECK_RESULT(ParseAction(&command->action)); + CHECK_RESULT(ParseQuotedText(&command->text)); + *out_command = std::move(command); } EXPECT(Rpar); return Result::Ok; @@ -1788,9 +1789,9 @@ Result WastParser::ParseAssertUnlinkableCommand(CommandPtr* out_command) { Result WastParser::ParseActionCommand(CommandPtr* out_command) { WABT_TRACE(ParseActionCommand); - auto action = make_unique<Action>(); - CHECK_RESULT(ParseAction(action.get())); - out_command->reset(new ActionCommand(action.release())); + auto command = MakeUnique<ActionCommand>(); + CHECK_RESULT(ParseAction(&command->action)); + *out_command = std::move(command); return Result::Ok; } @@ -1799,41 +1800,39 @@ Result WastParser::ParseModuleCommand(CommandPtr* out_command) { std::unique_ptr<ScriptModule> script_module; CHECK_RESULT(ParseScriptModule(&script_module)); - std::unique_ptr<Module> module; + auto command = MakeUnique<ModuleCommand>(); + auto&& module = command->module; - switch (script_module->type) { - case ScriptModule::Type::Text: - module.reset(script_module->text); - script_module->text = nullptr; + switch (script_module->type()) { + case ScriptModuleType::Text: + module = std::move(cast<TextScriptModule>(script_module.get())->module); break; - case ScriptModule::Type::Binary: { - module.reset(new Module()); + case ScriptModuleType::Binary: { + auto* bsm = cast<BinaryScriptModule>(script_module.get()); ReadBinaryOptions options; - BinaryErrorHandlerModule error_handler(&script_module->binary.loc, this); + BinaryErrorHandlerModule error_handler(&bsm->loc, this); const char* filename = "<text>"; - ReadBinaryIr(filename, script_module->binary.data.data(), - script_module->binary.data.size(), &options, &error_handler, - module.get()); - module->name = script_module->binary.name; - module->loc = script_module->binary.loc; + ReadBinaryIr(filename, bsm->data.data(), bsm->data.size(), &options, + &error_handler, &module); + module.name = bsm->name; + module.loc = bsm->loc; break; } - case ScriptModule::Type::Quoted: + case ScriptModuleType::Quoted: return ErrorExpected({"a binary module", "a text module"}); } Index command_index = script_->commands.size(); - if (!module->name.empty()) { - script_->module_bindings.emplace(module->name, - Binding(module->loc, command_index)); + if (!module.name.empty()) { + script_->module_bindings.emplace(module.name, + Binding(module.loc, command_index)); } last_module_index_ = command_index; - - out_command->reset(new ModuleCommand(module.release())); + *out_command = std::move(command); return Result::Ok; } @@ -1851,31 +1850,30 @@ Result WastParser::ParseRegisterCommand(CommandPtr* out_command) { return Result::Ok; } -Result WastParser::ParseAction(Action* out_action) { +Result WastParser::ParseAction(ActionPtr* out_action) { WABT_TRACE(ParseAction); EXPECT(Lpar); auto loc = GetLocation(); switch (Peek()) { - case TokenType::Invoke: - out_action->loc = loc; - out_action->type = ActionType::Invoke; - out_action->invoke = new ActionInvoke(); - + case TokenType::Invoke: { Consume(); - ParseVarOpt(&out_action->module_var, Var(last_module_index_, loc)); - CHECK_RESULT(ParseQuotedText(&out_action->name)); - CHECK_RESULT(ParseConstList(&out_action->invoke->args)); + auto action = MakeUnique<InvokeAction>(loc); + ParseVarOpt(&action->module_var, Var(last_module_index_, loc)); + CHECK_RESULT(ParseQuotedText(&action->name)); + CHECK_RESULT(ParseConstList(&action->args)); + *out_action = std::move(action); break; + } - case TokenType::Get: - out_action->loc = loc; - out_action->type = ActionType::Get; - + case TokenType::Get: { Consume(); - ParseVarOpt(&out_action->module_var, Var(last_module_index_, loc)); - CHECK_RESULT(ParseQuotedText(&out_action->name)); + auto action = MakeUnique<GetAction>(loc); + ParseVarOpt(&action->module_var, Var(last_module_index_, loc)); + CHECK_RESULT(ParseQuotedText(&action->name)); + *out_action = std::move(action); break; + } default: return ErrorExpected({"invoke", "get"}); @@ -1893,18 +1891,17 @@ Result WastParser::ParseScriptModule( std::string name; ParseBindVarOpt(&name); - std::unique_ptr<ScriptModule> script_module; - switch (Peek()) { case TokenType::Bin: { Consume(); std::vector<uint8_t> data; CHECK_RESULT(ParseTextList(&data)); - script_module = make_unique<ScriptModule>(ScriptModule::Type::Binary); - script_module->binary.name = name; - script_module->binary.loc = loc; - script_module->binary.data = std::move(data); + auto bsm = MakeUnique<BinaryScriptModule>(); + bsm->name = name; + bsm->loc = loc; + bsm->data = std::move(data); + *out_module = std::move(bsm); break; } @@ -1913,26 +1910,24 @@ Result WastParser::ParseScriptModule( std::vector<uint8_t> data; CHECK_RESULT(ParseTextList(&data)); - script_module = make_unique<ScriptModule>(ScriptModule::Type::Quoted); - script_module->quoted.name = name; - script_module->quoted.loc = loc; - script_module->quoted.data = std::move(data); + auto qsm = MakeUnique<QuotedScriptModule>(); + qsm->name = name; + qsm->loc = loc; + qsm->data = std::move(data); + *out_module = std::move(qsm); break; } default: { - script_module = make_unique<ScriptModule>(ScriptModule::Type::Text); - auto module = make_unique<Module>(); - module->loc = loc; - module->name = name; - CHECK_RESULT(ParseModuleFieldList(module.get())); - script_module->text = module.release(); + auto tsm = MakeUnique<TextScriptModule>(); + tsm->module.name = name; + tsm->module.loc = loc; + CHECK_RESULT(ParseModuleFieldList(&tsm->module)); + *out_module = std::move(tsm); break; } } - *out_module = std::move(script_module); - EXPECT(Rpar); return Result::Ok; } @@ -1943,10 +1938,10 @@ Result WastParser::ParseAssertActionCommand(TokenType token_type, WABT_TRACE(ParseAssertActionCommand); EXPECT(Lpar); CHECK_RESULT(Expect(token_type)); - auto action = make_unique<Action>(); - CHECK_RESULT(ParseAction(action.get())); + auto command = MakeUnique<T>(); + CHECK_RESULT(ParseAction(&command->action)); EXPECT(Rpar); - out_command->reset(new T(action.release())); + *out_command = std::move(command); return Result::Ok; } @@ -1956,12 +1951,11 @@ Result WastParser::ParseAssertActionTextCommand(TokenType token_type, WABT_TRACE(ParseAssertActionTextCommand); EXPECT(Lpar); CHECK_RESULT(Expect(token_type)); - auto action = make_unique<Action>(); - std::string text; - CHECK_RESULT(ParseAction(action.get())); - CHECK_RESULT(ParseQuotedText(&text)); + auto command = MakeUnique<T>(); + CHECK_RESULT(ParseAction(&command->action)); + CHECK_RESULT(ParseQuotedText(&command->text)); EXPECT(Rpar); - out_command->reset(new T(action.release(), text)); + *out_command = std::move(command); return Result::Ok; } @@ -1971,12 +1965,11 @@ Result WastParser::ParseAssertScriptModuleCommand(TokenType token_type, WABT_TRACE(ParseAssertScriptModuleCommand); EXPECT(Lpar); CHECK_RESULT(Expect(token_type)); - std::unique_ptr<ScriptModule> module; - std::string text; - CHECK_RESULT(ParseScriptModule(&module)); - CHECK_RESULT(ParseQuotedText(&text)); + auto command = MakeUnique<T>(); + CHECK_RESULT(ParseScriptModule(&command->module)); + CHECK_RESULT(ParseQuotedText(&command->text)); EXPECT(Rpar); - out_command->reset(new T(module.release(), text)); + *out_command = std::move(command); return Result::Ok; } @@ -1995,7 +1988,7 @@ Result ParseWast(WastLexer* lexer, Script** out_script, ErrorHandler* error_handler, WastParseOptions* options) { - auto script = make_unique<Script>(); + auto script = MakeUnique<Script>(); WastParser parser(lexer, error_handler, options); Result result = parser.ParseScript(script.get()); diff --git a/src/wast-parser.h b/src/wast-parser.h index 9a5d99a1..dc9fe11e 100644 --- a/src/wast-parser.h +++ b/src/wast-parser.h @@ -181,7 +181,7 @@ class WastParser { Result ParseModuleCommand(CommandPtr*); Result ParseRegisterCommand(CommandPtr*); - Result ParseAction(Action*); + Result ParseAction(ActionPtr*); Result ParseScriptModule(std::unique_ptr<ScriptModule>*); template <typename T> diff --git a/src/wat-writer.cc b/src/wat-writer.cc index e1ae580d..496899ce 100644 --- a/src/wat-writer.cc +++ b/src/wat-writer.cc @@ -94,7 +94,7 @@ class WatWriter { WatWriter(Writer* writer, const WriteWatOptions* options) : options_(options), stream_(writer) {} - Result WriteModule(const Module* module); + Result WriteModule(const Module& module); private: void Indent(); @@ -119,48 +119,48 @@ class WatWriter { void WriteNameOrIndex(string_view str, Index index, NextChar next_char); void WriteQuotedData(const void* data, size_t length); void WriteQuotedString(string_view str, NextChar next_char); - void WriteVar(const Var* var, NextChar next_char); - void WriteBrVar(const Var* var, NextChar next_char); + void WriteVar(const Var& var, NextChar next_char); + void WriteBrVar(const Var& var, NextChar next_char); void WriteType(Type type, NextChar next_char); void WriteTypes(const TypeVector& types, const char* name); - void WriteFuncSigSpace(const FuncSignature* func_sig); + void WriteFuncSigSpace(const FuncSignature& func_sig); void WriteBeginBlock(LabelType label_type, - const Block* block, + const Block& block, const char* text); void WriteEndBlock(); void WriteBlock(LabelType label_type, - const Block* block, + const Block& block, const char* start_text); - void WriteConst(const Const* const_); + void WriteConst(const Const& const_); void WriteExpr(const Expr* expr); void WriteExprList(const ExprList& exprs); void WriteInitExpr(const ExprList& expr); void WriteTypeBindings(const char* prefix, - const Func* func, + const Func& func, const TypeVector& types, const BindingHash& bindings); - void WriteFunc(const Module* module, const Func* func); - void WriteBeginGlobal(const Global* global); - void WriteGlobal(const Global* global); - void WriteBeginException(const Exception* except); - void WriteException(const Exception* except); - void WriteLimits(const Limits* limits); - void WriteTable(const Table* table); - void WriteElemSegment(const ElemSegment* segment); - void WriteMemory(const Memory* memory); - void WriteDataSegment(const DataSegment* segment); - void WriteImport(const Import* import); - void WriteExport(const Export* export_); - void WriteFuncType(const FuncType* func_type); - void WriteStartFunction(const Var* start); + void WriteFunc(const Module& module, const Func& func); + void WriteBeginGlobal(const Global& global); + void WriteGlobal(const Global& global); + void WriteBeginException(const Exception& except); + void WriteException(const Exception& except); + void WriteLimits(const Limits& limits); + void WriteTable(const Table& table); + void WriteElemSegment(const ElemSegment& segment); + void WriteMemory(const Memory& memory); + void WriteDataSegment(const DataSegment& segment); + void WriteImport(const Import& import); + void WriteExport(const Export& export_); + void WriteFuncType(const FuncType& func_type); + void WriteStartFunction(const Var& start); Index GetLabelStackSize() { return label_stack_.size(); } - Label* GetLabel(const Var* var); - Index GetLabelArity(const Var* var); - Index GetFuncParamCount(const Var* var); - Index GetFuncResultCount(const Var* var); - Index GetFuncSigParamCount(const Var* var); - Index GetFuncSigResultCount(const Var* var); + Label* GetLabel(const Var& var); + Index GetLabelArity(const Var& var); + Index GetFuncParamCount(const Var& var); + Index GetFuncResultCount(const Var& var); + Index GetFuncSigParamCount(const Var& var); + Index GetFuncSigResultCount(const Var& var); void PushExpr(const Expr* expr, Index operand_count, Index result_count); void FlushExprTree(const ExprTree& expr_tree); void FlushExprTreeVector(const std::vector<ExprTree>&); @@ -343,26 +343,26 @@ void WatWriter::WriteQuotedString(string_view str, NextChar next_char) { next_char_ = next_char; } -void WatWriter::WriteVar(const Var* var, NextChar next_char) { - if (var->is_index()) { - Writef("%" PRIindex, var->index()); +void WatWriter::WriteVar(const Var& var, NextChar next_char) { + if (var.is_index()) { + Writef("%" PRIindex, var.index()); next_char_ = next_char; } else { - WriteName(var->name(), next_char); + WriteName(var.name(), next_char); } } -void WatWriter::WriteBrVar(const Var* var, NextChar next_char) { - if (var->is_index()) { - if (var->index() < GetLabelStackSize()) { - Writef("%" PRIindex " (;@%" PRIindex ";)", var->index(), - GetLabelStackSize() - var->index() - 1); +void WatWriter::WriteBrVar(const Var& var, NextChar next_char) { + if (var.is_index()) { + if (var.index() < GetLabelStackSize()) { + Writef("%" PRIindex " (;@%" PRIindex ";)", var.index(), + GetLabelStackSize() - var.index() - 1); } else { - Writef("%" PRIindex " (; INVALID ;)", var->index()); + Writef("%" PRIindex " (; INVALID ;)", var.index()); } next_char_ = next_char; } else { - WriteString(var->name(), next_char); + WriteString(var.name(), next_char); } } @@ -383,23 +383,23 @@ void WatWriter::WriteTypes(const TypeVector& types, const char* name) { } } -void WatWriter::WriteFuncSigSpace(const FuncSignature* func_sig) { - WriteTypes(func_sig->param_types, "param"); - WriteTypes(func_sig->result_types, "result"); +void WatWriter::WriteFuncSigSpace(const FuncSignature& func_sig) { + WriteTypes(func_sig.param_types, "param"); + WriteTypes(func_sig.result_types, "result"); } void WatWriter::WriteBeginBlock(LabelType label_type, - const Block* block, + const Block& block, const char* text) { WritePutsSpace(text); - bool has_label = !block->label.empty(); + bool has_label = !block.label.empty(); if (has_label) - WriteString(block->label, NextChar::Space); - WriteTypes(block->sig, "result"); + WriteString(block.label, NextChar::Space); + WriteTypes(block.sig, "result"); if (!has_label) Writef(" ;; label = @%" PRIindex, GetLabelStackSize()); WriteNewline(FORCE_NEWLINE); - label_stack_.emplace_back(label_type, block->label, block->sig); + label_stack_.emplace_back(label_type, block.label, block.sig); Indent(); } @@ -410,34 +410,34 @@ void WatWriter::WriteEndBlock() { } void WatWriter::WriteBlock(LabelType label_type, - const Block* block, + const Block& block, const char* start_text) { WriteBeginBlock(label_type, block, start_text); - WriteExprList(block->exprs); + WriteExprList(block.exprs); WriteEndBlock(); } -void WatWriter::WriteConst(const Const* const_) { - switch (const_->type) { +void WatWriter::WriteConst(const Const& const_) { + switch (const_.type) { case Type::I32: WritePutsSpace(Opcode::I32Const_Opcode.GetName()); - Writef("%d", static_cast<int32_t>(const_->u32)); + Writef("%d", static_cast<int32_t>(const_.u32)); WriteNewline(NO_FORCE_NEWLINE); break; case Type::I64: WritePutsSpace(Opcode::I64Const_Opcode.GetName()); - Writef("%" PRId64, static_cast<int64_t>(const_->u64)); + Writef("%" PRId64, static_cast<int64_t>(const_.u64)); WriteNewline(NO_FORCE_NEWLINE); break; case Type::F32: { WritePutsSpace(Opcode::F32Const_Opcode.GetName()); char buffer[128]; - WriteFloatHex(buffer, 128, const_->f32_bits); + WriteFloatHex(buffer, 128, const_.f32_bits); WritePutsSpace(buffer); float f32; - memcpy(&f32, &const_->f32_bits, sizeof(f32)); + memcpy(&f32, &const_.f32_bits, sizeof(f32)); Writef("(;=%g;)", f32); WriteNewline(NO_FORCE_NEWLINE); break; @@ -446,10 +446,10 @@ void WatWriter::WriteConst(const Const* const_) { case Type::F64: { WritePutsSpace(Opcode::F64Const_Opcode.GetName()); char buffer[128]; - WriteDoubleHex(buffer, 128, const_->f64_bits); + WriteDoubleHex(buffer, 128, const_.f64_bits); WritePutsSpace(buffer); double f64; - memcpy(&f64, &const_->f64_bits, sizeof(f64)); + memcpy(&f64, &const_.f64_bits, sizeof(f64)); Writef("(;=%g;)", f64); WriteNewline(NO_FORCE_NEWLINE); break; @@ -463,7 +463,7 @@ void WatWriter::WriteConst(const Const* const_) { void WatWriter::WriteExpr(const Expr* expr) { WABT_TRACE_ARGS(WriteExpr, "%s", GetExprTypeName(*expr)); - switch (expr->type) { + switch (expr->type()) { case ExprType::Binary: WritePutsNewline(cast<BinaryExpr>(expr)->opcode.GetName()); break; @@ -475,30 +475,30 @@ void WatWriter::WriteExpr(const Expr* expr) { case ExprType::Br: WritePutsSpace(Opcode::Br_Opcode.GetName()); - WriteBrVar(&cast<BrExpr>(expr)->var, NextChar::Newline); + WriteBrVar(cast<BrExpr>(expr)->var, NextChar::Newline); break; case ExprType::BrIf: WritePutsSpace(Opcode::BrIf_Opcode.GetName()); - WriteBrVar(&cast<BrIfExpr>(expr)->var, NextChar::Newline); + WriteBrVar(cast<BrIfExpr>(expr)->var, NextChar::Newline); break; case ExprType::BrTable: { WritePutsSpace(Opcode::BrTable_Opcode.GetName()); - for (const Var& var : *cast<BrTableExpr>(expr)->targets) - WriteBrVar(&var, NextChar::Space); - WriteBrVar(&cast<BrTableExpr>(expr)->default_target, NextChar::Newline); + for (const Var& var : cast<BrTableExpr>(expr)->targets) + WriteBrVar(var, NextChar::Space); + WriteBrVar(cast<BrTableExpr>(expr)->default_target, NextChar::Newline); break; } case ExprType::Call: WritePutsSpace(Opcode::Call_Opcode.GetName()); - WriteVar(&cast<CallExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<CallExpr>(expr)->var, NextChar::Newline); break; case ExprType::CallIndirect: WritePutsSpace(Opcode::CallIndirect_Opcode.GetName()); - WriteVar(&cast<CallIndirectExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<CallIndirectExpr>(expr)->var, NextChar::Newline); break; case ExprType::Compare: @@ -506,7 +506,7 @@ void WatWriter::WriteExpr(const Expr* expr) { break; case ExprType::Const: - WriteConst(&cast<ConstExpr>(expr)->const_); + WriteConst(cast<ConstExpr>(expr)->const_); break; case ExprType::Convert: @@ -519,12 +519,12 @@ void WatWriter::WriteExpr(const Expr* expr) { case ExprType::GetGlobal: WritePutsSpace(Opcode::GetGlobal_Opcode.GetName()); - WriteVar(&cast<GetGlobalExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<GetGlobalExpr>(expr)->var, NextChar::Newline); break; case ExprType::GetLocal: WritePutsSpace(Opcode::GetLocal_Opcode.GetName()); - WriteVar(&cast<GetLocalExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<GetLocalExpr>(expr)->var, NextChar::Newline); break; case ExprType::GrowMemory: @@ -535,7 +535,7 @@ void WatWriter::WriteExpr(const Expr* expr) { auto if_expr = cast<IfExpr>(expr); WriteBeginBlock(LabelType::If, if_expr->true_, Opcode::If_Opcode.GetName()); - WriteExprList(if_expr->true_->exprs); + WriteExprList(if_expr->true_.exprs); if (!if_expr->false_.empty()) { Dedent(); WritePutsSpace(Opcode::Else_Opcode.GetName()); @@ -573,7 +573,7 @@ void WatWriter::WriteExpr(const Expr* expr) { case ExprType::Rethrow: WritePutsSpace(Opcode::Rethrow_Opcode.GetName()); - WriteBrVar(&cast<RethrowExpr>(expr)->var, NextChar::Newline); + WriteBrVar(cast<RethrowExpr>(expr)->var, NextChar::Newline); break; case ExprType::Return: @@ -586,12 +586,12 @@ void WatWriter::WriteExpr(const Expr* expr) { case ExprType::SetGlobal: WritePutsSpace(Opcode::SetGlobal_Opcode.GetName()); - WriteVar(&cast<SetGlobalExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<SetGlobalExpr>(expr)->var, NextChar::Newline); break; case ExprType::SetLocal: WritePutsSpace(Opcode::SetLocal_Opcode.GetName()); - WriteVar(&cast<SetLocalExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<SetLocalExpr>(expr)->var, NextChar::Newline); break; case ExprType::Store: { @@ -607,30 +607,30 @@ void WatWriter::WriteExpr(const Expr* expr) { case ExprType::TeeLocal: WritePutsSpace(Opcode::TeeLocal_Opcode.GetName()); - WriteVar(&cast<TeeLocalExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<TeeLocalExpr>(expr)->var, NextChar::Newline); break; case ExprType::Throw: WritePutsSpace(Opcode::Throw_Opcode.GetName()); - WriteVar(&cast<ThrowExpr>(expr)->var, NextChar::Newline); + WriteVar(cast<ThrowExpr>(expr)->var, NextChar::Newline); break; case ExprType::TryBlock: { auto try_ = cast<TryExpr>(expr); WriteBeginBlock(LabelType::Try, try_->block, Opcode::Try_Opcode.GetName()); - WriteExprList(try_->block->exprs); - for (const Catch* catch_ : try_->catches) { + WriteExprList(try_->block.exprs); + for (const Catch& catch_ : try_->catches) { Dedent(); - if (catch_->IsCatchAll()) { + if (catch_.IsCatchAll()) { WritePutsNewline(Opcode::CatchAll_Opcode.GetName()); } else { WritePutsSpace(Opcode::Catch_Opcode.GetName()); - WriteVar(&catch_->var, NextChar::Newline); + WriteVar(catch_.var, NextChar::Newline); } Indent(); label_stack_.back().label_type = LabelType::Catch; - WriteExprList(catch_->exprs); + WriteExprList(catch_.exprs); } WriteEndBlock(); break; @@ -657,49 +657,49 @@ void WatWriter::WriteExprList(const ExprList& exprs) { WriteExpr(&expr); } -Label* WatWriter::GetLabel(const Var* var) { - if (var->is_name()) { +Label* WatWriter::GetLabel(const Var& var) { + if (var.is_name()) { for (Index i = GetLabelStackSize(); i > 0; --i) { Label* label = &label_stack_[i - 1]; - if (label->name == var->name()) + if (label->name == var.name()) return label; } - } else if (var->index() < GetLabelStackSize()) { - Label* label = &label_stack_[GetLabelStackSize() - var->index() - 1]; + } else if (var.index() < GetLabelStackSize()) { + Label* label = &label_stack_[GetLabelStackSize() - var.index() - 1]; return label; } return nullptr; } -Index WatWriter::GetLabelArity(const Var* var) { +Index WatWriter::GetLabelArity(const Var& var) { Label* label = GetLabel(var); return label && label->label_type != LabelType::Loop ? label->sig.size() : 0; } -Index WatWriter::GetFuncParamCount(const Var* var) { - const Func* func = module_->GetFunc(*var); +Index WatWriter::GetFuncParamCount(const Var& var) { + const Func* func = module_->GetFunc(var); return func ? func->GetNumParams() : 0; } -Index WatWriter::GetFuncResultCount(const Var* var) { - const Func* func = module_->GetFunc(*var); +Index WatWriter::GetFuncResultCount(const Var& var) { + const Func* func = module_->GetFunc(var); return func ? func->GetNumResults() : 0; } -Index WatWriter::GetFuncSigParamCount(const Var* var) { - const FuncType* func_type = module_->GetFuncType(*var); +Index WatWriter::GetFuncSigParamCount(const Var& var) { + const FuncType* func_type = module_->GetFuncType(var); return func_type ? func_type->GetNumParams() : 0; } -Index WatWriter::GetFuncSigResultCount(const Var* var) { - const FuncType* func_type = module_->GetFuncType(*var); +Index WatWriter::GetFuncSigResultCount(const Var& var) { + const FuncType* func_type = module_->GetFuncType(var); return func_type ? func_type->GetNumResults() : 0; } void WatWriter::WriteFoldedExpr(const Expr* expr) { WABT_TRACE_ARGS(WriteFoldedExpr, "%s", GetExprTypeName(*expr)); - switch (expr->type) { + switch (expr->type()) { case ExprType::Binary: case ExprType::Compare: case ExprType::Store: @@ -707,34 +707,34 @@ void WatWriter::WriteFoldedExpr(const Expr* expr) { break; case ExprType::Block: - PushExpr(expr, 0, cast<BlockExpr>(expr)->block->sig.size()); + PushExpr(expr, 0, cast<BlockExpr>(expr)->block.sig.size()); break; case ExprType::Br: - PushExpr(expr, GetLabelArity(&cast<BrExpr>(expr)->var), 1); + PushExpr(expr, GetLabelArity(cast<BrExpr>(expr)->var), 1); break; case ExprType::BrIf: { - Index arity = GetLabelArity(&cast<BrIfExpr>(expr)->var); + Index arity = GetLabelArity(cast<BrIfExpr>(expr)->var); PushExpr(expr, arity + 1, arity); break; } case ExprType::BrTable: - PushExpr(expr, - GetLabelArity(&cast<BrTableExpr>(expr)->default_target) + 1, 1); + PushExpr(expr, GetLabelArity(cast<BrTableExpr>(expr)->default_target) + 1, + 1); break; case ExprType::Call: { const Var& var = cast<CallExpr>(expr)->var; - PushExpr(expr, GetFuncParamCount(&var), GetFuncResultCount(&var)); + PushExpr(expr, GetFuncParamCount(var), GetFuncResultCount(var)); break; } case ExprType::CallIndirect: { const Var& var = cast<CallIndirectExpr>(expr)->var; - PushExpr(expr, GetFuncSigParamCount(&var) + 1, - GetFuncSigResultCount(&var)); + PushExpr(expr, GetFuncSigParamCount(var) + 1, + GetFuncSigResultCount(var)); break; } @@ -761,11 +761,11 @@ void WatWriter::WriteFoldedExpr(const Expr* expr) { break; case ExprType::If: - PushExpr(expr, 1, cast<IfExpr>(expr)->true_->sig.size()); + PushExpr(expr, 1, cast<IfExpr>(expr)->true_.sig.size()); break; case ExprType::Loop: - PushExpr(expr, 0, cast<LoopExpr>(expr)->block->sig.size()); + PushExpr(expr, 0, cast<LoopExpr>(expr)->block.sig.size()); break; case ExprType::Nop: @@ -795,7 +795,7 @@ void WatWriter::WriteFoldedExpr(const Expr* expr) { } case ExprType::TryBlock: - PushExpr(expr, 0, cast<TryExpr>(expr)->block->sig.size()); + PushExpr(expr, 0, cast<TryExpr>(expr)->block.sig.size()); break; default: @@ -833,12 +833,12 @@ void WatWriter::PushExpr(const Expr* expr, void WatWriter::FlushExprTree(const ExprTree& expr_tree) { WABT_TRACE_ARGS(FlushExprTree, "%s", GetExprTypeName(*expr_tree.expr)); - switch (expr_tree.expr->type) { + switch (expr_tree.expr->type()) { case ExprType::Block: WritePuts("(", NextChar::None); WriteBeginBlock(LabelType::Block, cast<BlockExpr>(expr_tree.expr)->block, Opcode::Block_Opcode.GetName()); - WriteFoldedExprList(cast<BlockExpr>(expr_tree.expr)->block->exprs); + WriteFoldedExprList(cast<BlockExpr>(expr_tree.expr)->block.exprs); FlushExprTreeStack(); WriteCloseNewline(); break; @@ -847,7 +847,7 @@ void WatWriter::FlushExprTree(const ExprTree& expr_tree) { WritePuts("(", NextChar::None); WriteBeginBlock(LabelType::Loop, cast<LoopExpr>(expr_tree.expr)->block, Opcode::Loop_Opcode.GetName()); - WriteFoldedExprList(cast<LoopExpr>(expr_tree.expr)->block->exprs); + WriteFoldedExprList(cast<LoopExpr>(expr_tree.expr)->block.exprs); FlushExprTreeStack(); WriteCloseNewline(); break; @@ -859,7 +859,7 @@ void WatWriter::FlushExprTree(const ExprTree& expr_tree) { Opcode::If_Opcode.GetName()); FlushExprTreeVector(expr_tree.children); WriteOpenNewline("then"); - WriteFoldedExprList(if_expr->true_->exprs); + WriteFoldedExprList(if_expr->true_.exprs); FlushExprTreeStack(); WriteCloseNewline(); if (!if_expr->false_.empty()) { @@ -877,19 +877,19 @@ void WatWriter::FlushExprTree(const ExprTree& expr_tree) { WritePuts("(", NextChar::None); WriteBeginBlock(LabelType::Try, try_->block, Opcode::Try_Opcode.GetName()); - WriteFoldedExprList(try_->block->exprs); + WriteFoldedExprList(try_->block.exprs); FlushExprTreeStack(); - for (const Catch* catch_ : try_->catches) { + for (const Catch& catch_ : try_->catches) { WritePuts("(", NextChar::None); - if (catch_->IsCatchAll()) { + if (catch_.IsCatchAll()) { WritePutsNewline(Opcode::CatchAll_Opcode.GetName()); } else { WritePutsSpace(Opcode::Catch_Opcode.GetName()); - WriteVar(&catch_->var, NextChar::Newline); + WriteVar(catch_.var, NextChar::Newline); } Indent(); label_stack_.back().label_type = LabelType::Catch; - WriteFoldedExprList(catch_->exprs); + WriteFoldedExprList(catch_.exprs); FlushExprTreeStack(); WriteCloseNewline(); } @@ -931,7 +931,7 @@ void WatWriter::WriteInitExpr(const ExprList& expr) { } void WatWriter::WriteTypeBindings(const char* prefix, - const Func* func, + const Func& func, const TypeVector& types, const BindingHash& bindings) { MakeTypeBindingReverseMapping(types, bindings, &index_to_name_); @@ -961,182 +961,184 @@ void WatWriter::WriteTypeBindings(const char* prefix, WriteCloseSpace(); } -void WatWriter::WriteFunc(const Module* module, const Func* func) { +void WatWriter::WriteFunc(const Module& module, const Func& func) { WriteOpenSpace("func"); - WriteNameOrIndex(func->name, func_index_, NextChar::Space); + WriteNameOrIndex(func.name, func_index_, NextChar::Space); WriteInlineExports(ExternalKind::Func, func_index_); - if (func->decl.has_func_type) { + if (func.decl.has_func_type) { WriteOpenSpace("type"); - WriteVar(&func->decl.type_var, NextChar::None); + WriteVar(func.decl.type_var, NextChar::None); WriteCloseSpace(); } - WriteTypeBindings("param", func, func->decl.sig.param_types, - func->param_bindings); - WriteTypes(func->decl.sig.result_types, "result"); + WriteTypeBindings("param", func, func.decl.sig.param_types, + func.param_bindings); + WriteTypes(func.decl.sig.result_types, "result"); WriteNewline(NO_FORCE_NEWLINE); - if (func->local_types.size()) { - WriteTypeBindings("local", func, func->local_types, func->local_bindings); + if (func.local_types.size()) { + WriteTypeBindings("local", func, func.local_types, func.local_bindings); } WriteNewline(NO_FORCE_NEWLINE); label_stack_.clear(); label_stack_.emplace_back(LabelType::Func, std::string(), - func->decl.sig.result_types); - current_func_ = func; + func.decl.sig.result_types); + current_func_ = &func; if (options_->fold_exprs) { - WriteFoldedExprList(func->exprs); + WriteFoldedExprList(func.exprs); FlushExprTreeStack(); } else { - WriteExprList(func->exprs); + WriteExprList(func.exprs); } current_func_ = nullptr; WriteCloseNewline(); func_index_++; } -void WatWriter::WriteBeginGlobal(const Global* global) { +void WatWriter::WriteBeginGlobal(const Global& global) { WriteOpenSpace("global"); - WriteNameOrIndex(global->name, global_index_, NextChar::Space); + WriteNameOrIndex(global.name, global_index_, NextChar::Space); WriteInlineExports(ExternalKind::Global, global_index_); - if (global->mutable_) { + if (global.mutable_) { WriteOpenSpace("mut"); - WriteType(global->type, NextChar::Space); + WriteType(global.type, NextChar::Space); WriteCloseSpace(); } else { - WriteType(global->type, NextChar::Space); + WriteType(global.type, NextChar::Space); } global_index_++; } -void WatWriter::WriteGlobal(const Global* global) { +void WatWriter::WriteGlobal(const Global& global) { WriteBeginGlobal(global); - WriteInitExpr(global->init_expr); + WriteInitExpr(global.init_expr); WriteCloseNewline(); } -void WatWriter::WriteBeginException(const Exception* except) { +void WatWriter::WriteBeginException(const Exception& except) { WriteOpenSpace("except"); - WriteNameOrIndex(except->name, except_index_, NextChar::Space); + WriteNameOrIndex(except.name, except_index_, NextChar::Space); WriteInlineExports(ExternalKind::Except, except_index_); - WriteTypes(except->sig, nullptr); + WriteTypes(except.sig, nullptr); ++except_index_; } -void WatWriter::WriteException(const Exception* except) { +void WatWriter::WriteException(const Exception& except) { WriteBeginException(except); WriteCloseNewline(); } -void WatWriter::WriteLimits(const Limits* limits) { - Writef("%" PRIu64, limits->initial); - if (limits->has_max) - Writef("%" PRIu64, limits->max); +void WatWriter::WriteLimits(const Limits& limits) { + Writef("%" PRIu64, limits.initial); + if (limits.has_max) + Writef("%" PRIu64, limits.max); } -void WatWriter::WriteTable(const Table* table) { +void WatWriter::WriteTable(const Table& table) { WriteOpenSpace("table"); - WriteNameOrIndex(table->name, table_index_, NextChar::Space); + WriteNameOrIndex(table.name, table_index_, NextChar::Space); WriteInlineExports(ExternalKind::Table, table_index_); - WriteLimits(&table->elem_limits); + WriteLimits(table.elem_limits); WritePutsSpace("anyfunc"); WriteCloseNewline(); table_index_++; } -void WatWriter::WriteElemSegment(const ElemSegment* segment) { +void WatWriter::WriteElemSegment(const ElemSegment& segment) { WriteOpenSpace("elem"); - WriteInitExpr(segment->offset); - for (const Var& var : segment->vars) - WriteVar(&var, NextChar::Space); + WriteInitExpr(segment.offset); + for (const Var& var : segment.vars) + WriteVar(var, NextChar::Space); WriteCloseNewline(); } -void WatWriter::WriteMemory(const Memory* memory) { +void WatWriter::WriteMemory(const Memory& memory) { WriteOpenSpace("memory"); - WriteNameOrIndex(memory->name, memory_index_, NextChar::Space); + WriteNameOrIndex(memory.name, memory_index_, NextChar::Space); WriteInlineExports(ExternalKind::Memory, memory_index_); - WriteLimits(&memory->page_limits); + WriteLimits(memory.page_limits); WriteCloseNewline(); memory_index_++; } -void WatWriter::WriteDataSegment(const DataSegment* segment) { +void WatWriter::WriteDataSegment(const DataSegment& segment) { WriteOpenSpace("data"); - WriteInitExpr(segment->offset); - WriteQuotedData(segment->data.data(), segment->data.size()); + WriteInitExpr(segment.offset); + WriteQuotedData(segment.data.data(), segment.data.size()); WriteCloseNewline(); } -void WatWriter::WriteImport(const Import* import) { +void WatWriter::WriteImport(const Import& import) { WriteOpenSpace("import"); - WriteQuotedString(import->module_name, NextChar::Space); - WriteQuotedString(import->field_name, NextChar::Space); - switch (import->kind) { - case ExternalKind::Func: + WriteQuotedString(import.module_name, NextChar::Space); + WriteQuotedString(import.field_name, NextChar::Space); + switch (import.kind()) { + case ExternalKind::Func: { + auto* func_import = cast<FuncImport>(&import); WriteOpenSpace("func"); - WriteNameOrIndex(import->func->name, func_index_++, NextChar::Space); - if (import->func->decl.has_func_type) { + WriteNameOrIndex(func_import->func.name, func_index_++, NextChar::Space); + if (func_import->func.decl.has_func_type) { WriteOpenSpace("type"); - WriteVar(&import->func->decl.type_var, NextChar::None); + WriteVar(func_import->func.decl.type_var, NextChar::None); WriteCloseSpace(); } else { - WriteFuncSigSpace(&import->func->decl.sig); + WriteFuncSigSpace(func_import->func.decl.sig); } WriteCloseSpace(); break; + } case ExternalKind::Table: - WriteTable(import->table); + WriteTable(cast<TableImport>(&import)->table); break; case ExternalKind::Memory: - WriteMemory(import->memory); + WriteMemory(cast<MemoryImport>(&import)->memory); break; case ExternalKind::Global: - WriteBeginGlobal(import->global); + WriteBeginGlobal(cast<GlobalImport>(&import)->global); WriteCloseSpace(); break; case ExternalKind::Except: - WriteBeginException(import->except); + WriteBeginException(cast<ExceptionImport>(&import)->except); WriteCloseSpace(); break; } WriteCloseNewline(); } -void WatWriter::WriteExport(const Export* export_) { +void WatWriter::WriteExport(const Export& export_) { if (options_->inline_export) return; WriteOpenSpace("export"); - WriteQuotedString(export_->name, NextChar::Space); - WriteOpenSpace(GetKindName(export_->kind)); - WriteVar(&export_->var, NextChar::Space); + WriteQuotedString(export_.name, NextChar::Space); + WriteOpenSpace(GetKindName(export_.kind)); + WriteVar(export_.var, NextChar::Space); WriteCloseSpace(); WriteCloseNewline(); } -void WatWriter::WriteFuncType(const FuncType* func_type) { +void WatWriter::WriteFuncType(const FuncType& func_type) { WriteOpenSpace("type"); - WriteNameOrIndex(func_type->name, func_type_index_++, NextChar::Space); + WriteNameOrIndex(func_type.name, func_type_index_++, NextChar::Space); WriteOpenSpace("func"); - WriteFuncSigSpace(&func_type->sig); + WriteFuncSigSpace(func_type.sig); WriteCloseSpace(); WriteCloseNewline(); } -void WatWriter::WriteStartFunction(const Var* start) { +void WatWriter::WriteStartFunction(const Var& start) { WriteOpenSpace("start"); WriteVar(start, NextChar::None); WriteCloseNewline(); } -Result WatWriter::WriteModule(const Module* module) { - module_ = module; +Result WatWriter::WriteModule(const Module& module) { + module_ = &module; BuildExportMap(); WriteOpenNewline("module"); - for (const ModuleField& field : module->fields) { - switch (field.type) { + for (const ModuleField& field : module.fields) { + switch (field.type()) { case ModuleFieldType::Func: WriteFunc(module, cast<FuncModuleField>(&field)->func); break; @@ -1144,7 +1146,7 @@ Result WatWriter::WriteModule(const Module* module) { WriteGlobal(cast<GlobalModuleField>(&field)->global); break; case ModuleFieldType::Import: - WriteImport(cast<ImportModuleField>(&field)->import); + WriteImport(*cast<ImportModuleField>(&field)->import); break; case ModuleFieldType::Except: WriteException(cast<ExceptionModuleField>(&field)->except); @@ -1168,7 +1170,7 @@ Result WatWriter::WriteModule(const Module* module) { WriteFuncType(cast<FuncTypeModuleField>(&field)->func_type); break; case ModuleFieldType::Start: - WriteStartFunction(&cast<StartModuleField>(&field)->start); + WriteStartFunction(cast<StartModuleField>(&field)->start); break; } } @@ -1235,7 +1237,7 @@ Result WriteWat(Writer* writer, const Module* module, const WriteWatOptions* options) { WatWriter wat_writer(writer, options); - return wat_writer.WriteModule(module); + return wat_writer.WriteModule(*module); } } // namespace wabt |