summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/apply-names.cc11
-rw-r--r--src/binary-reader-ir.cc422
-rw-r--r--src/binary-reader-linker.cc2
-rw-r--r--src/binary-writer-spec.cc170
-rw-r--r--src/binary-writer.cc49
-rw-r--r--src/common.h19
-rw-r--r--src/expr-visitor.cc16
-rw-r--r--src/generate-names.cc6
-rw-r--r--src/interpreter.h4
-rw-r--r--src/ir.cc228
-rw-r--r--src/ir.h455
-rw-r--r--src/resolve-names.cc23
-rw-r--r--src/tools/wasm-link.cc3
-rw-r--r--src/validator.cc146
-rw-r--r--src/wasm-link.h2
-rw-r--r--src/wast-parser.cc589
-rw-r--r--src/wast-parser.h2
-rw-r--r--src/wat-writer.cc370
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) {}
diff --git a/src/ir.cc b/src/ir.cc
index df58768d..685f2307 100644
--- a/src/ir.cc
+++ b/src/ir.cc
@@ -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
diff --git a/src/ir.h b/src/ir.h
index 9bd30ade..1503219a 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -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