summaryrefslogtreecommitdiff
path: root/src/wast-parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/wast-parser.cc')
-rw-r--r--src/wast-parser.cc589
1 files changed, 291 insertions, 298 deletions
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());