diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/binary-writer-spec.cc | 126 | ||||
-rw-r--r-- | src/ir.cc | 60 | ||||
-rw-r--r-- | src/ir.h | 122 | ||||
-rw-r--r-- | src/prebuilt/wast-parser-gen.cc | 184 | ||||
-rw-r--r-- | src/resolve-names.cc | 20 | ||||
-rw-r--r-- | src/validator.cc | 23 | ||||
-rw-r--r-- | src/wast-parser.y | 92 |
7 files changed, 308 insertions, 319 deletions
diff --git a/src/binary-writer-spec.cc b/src/binary-writer-spec.cc index e0b01c95..4d1c25ec 100644 --- a/src/binary-writer-spec.cc +++ b/src/binary-writer-spec.cc @@ -21,6 +21,7 @@ #include "binary.h" #include "binary-writer.h" +#include "cast.h" #include "config.h" #include "ir.h" #include "stream.h" @@ -177,8 +178,6 @@ void BinaryWriterSpec::WriteCommandType(const Command& command) { "register", "assert_malformed", "assert_invalid", - nullptr, /* ASSERT_INVALID_NON_BINARY, this command will never be - written */ "assert_unlinkable", "assert_uninstantiable", "assert_return", @@ -411,10 +410,7 @@ void BinaryWriterSpec::WriteCommands(Script* script) { 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(); - - if (command.type == CommandType::AssertInvalidNonBinary) - continue; + const Command* command = script->commands[i].get(); if (i != 0) { WriteSeparator(); @@ -422,12 +418,12 @@ void BinaryWriterSpec::WriteCommands(Script* script) { } json_stream_.Writef(" {"); - WriteCommandType(command); + WriteCommandType(*command); WriteSeparator(); - switch (command.type) { + switch (command->type) { case CommandType::Module: { - Module* module = command.module; + Module* module = cast<ModuleCommand>(command)->module; char* filename = GetModuleFilename(kWasmExtension); WriteLocation(&module->loc); WriteSeparator(); @@ -445,100 +441,124 @@ void BinaryWriterSpec::WriteCommands(Script* script) { break; } - case CommandType::Action: - WriteLocation(&command.action->loc); + case CommandType::Action: { + const Action* action = cast<ActionCommand>(command)->action; + WriteLocation(&action->loc); WriteSeparator(); - WriteAction(command.action); + WriteAction(action); break; + } - case CommandType::Register: - WriteLocation(&command.register_.var.loc); + case CommandType::Register: { + auto* register_command = cast<RegisterCommand>(command); + const Var& var = register_command->var; + WriteLocation(&var.loc); WriteSeparator(); - if (command.register_.var.type == VarType::Name) { + if (var.type == VarType::Name) { WriteKey("name"); - WriteVar(&command.register_.var); + WriteVar(&var); WriteSeparator(); } else { /* If we're not registering by name, then we should only be * registering the last module. */ WABT_USE(last_module_index); - assert(command.register_.var.index == last_module_index); + assert(var.index == last_module_index); } WriteKey("as"); - WriteEscapedStringSlice(command.register_.module_name); + WriteEscapedStringSlice(register_command->module_name); break; + } - case CommandType::AssertMalformed: - WriteInvalidModule(command.assert_malformed.module, - command.assert_malformed.text); + case CommandType::AssertMalformed: { + auto* assert_malformed_command = cast<AssertMalformedCommand>(command); + WriteInvalidModule(assert_malformed_command->module, + assert_malformed_command->text); num_modules_++; break; + } - case CommandType::AssertInvalid: - WriteInvalidModule(command.assert_invalid.module, - command.assert_invalid.text); + case CommandType::AssertInvalid: { + auto* assert_invalid_command = cast<AssertInvalidCommand>(command); + WriteInvalidModule(assert_invalid_command->module, + assert_invalid_command->text); num_modules_++; break; + } - case CommandType::AssertUnlinkable: - WriteInvalidModule(command.assert_unlinkable.module, - command.assert_unlinkable.text); + case CommandType::AssertUnlinkable: { + auto* assert_unlinkable_command = + cast<AssertUnlinkableCommand>(command); + WriteInvalidModule(assert_unlinkable_command->module, + assert_unlinkable_command->text); num_modules_++; break; + } - case CommandType::AssertUninstantiable: - WriteInvalidModule(command.assert_uninstantiable.module, - command.assert_uninstantiable.text); + case CommandType::AssertUninstantiable: { + auto* assert_uninstantiable_command = + cast<AssertUninstantiableCommand>(command); + WriteInvalidModule(assert_uninstantiable_command->module, + assert_uninstantiable_command->text); num_modules_++; break; + } - case CommandType::AssertReturn: - WriteLocation(&command.assert_return.action->loc); + case CommandType::AssertReturn: { + auto* assert_return_command = cast<AssertReturnCommand>(command); + WriteLocation(&assert_return_command->action->loc); WriteSeparator(); - WriteAction(command.assert_return.action); + WriteAction(assert_return_command->action); WriteSeparator(); WriteKey("expected"); - WriteConstVector(*command.assert_return.expected); + WriteConstVector(*assert_return_command->expected); break; + } - case CommandType::AssertReturnCanonicalNan: - WriteLocation(&command.assert_return_canonical_nan.action->loc); + case CommandType::AssertReturnCanonicalNan: { + auto* assert_return_canonical_nan_command = + cast<AssertReturnCanonicalNanCommand>(command); + WriteLocation(&assert_return_canonical_nan_command->action->loc); WriteSeparator(); - WriteAction(command.assert_return_canonical_nan.action); + WriteAction(assert_return_canonical_nan_command->action); WriteSeparator(); WriteKey("expected"); WriteActionResultType(script, - command.assert_return_canonical_nan.action); + assert_return_canonical_nan_command->action); break; + } - case CommandType::AssertReturnArithmeticNan: - WriteLocation(&command.assert_return_arithmetic_nan.action->loc); + case CommandType::AssertReturnArithmeticNan: { + auto* assert_return_arithmetic_nan_command = + cast<AssertReturnArithmeticNanCommand>(command); + WriteLocation(&assert_return_arithmetic_nan_command->action->loc); WriteSeparator(); - WriteAction(command.assert_return_arithmetic_nan.action); + WriteAction(assert_return_arithmetic_nan_command->action); WriteSeparator(); WriteKey("expected"); WriteActionResultType(script, - command.assert_return_arithmetic_nan.action); + assert_return_arithmetic_nan_command->action); break; + } - case CommandType::AssertTrap: - WriteLocation(&command.assert_trap.action->loc); + case CommandType::AssertTrap: { + auto* assert_trap_command = cast<AssertTrapCommand>(command); + WriteLocation(&assert_trap_command->action->loc); WriteSeparator(); - WriteAction(command.assert_trap.action); + WriteAction(assert_trap_command->action); WriteSeparator(); WriteKey("text"); - WriteEscapedStringSlice(command.assert_trap.text); + WriteEscapedStringSlice(assert_trap_command->text); break; + } - case CommandType::AssertExhaustion: - WriteLocation(&command.assert_trap.action->loc); + case CommandType::AssertExhaustion: { + auto* assert_exhaustion_command = + cast<AssertExhaustionCommand>(command); + WriteLocation(&assert_exhaustion_command->action->loc); WriteSeparator(); - WriteAction(command.assert_trap.action); - break; - - case CommandType::AssertInvalidNonBinary: - assert(0); + WriteAction(assert_exhaustion_command->action); break; + } } json_stream_.Writef("}"); @@ -19,6 +19,8 @@ #include <cassert> #include <cstddef> +#include "cast.h" + namespace { const char* ExprTypeName[] = { @@ -195,8 +197,8 @@ const Module* Script::GetFirstModule() const { Module* Script::GetFirstModule() { for (const std::unique_ptr<Command>& command : commands) { - if (command->type == CommandType::Module) - return command->module; + if (auto* module_command = dyn_cast<ModuleCommand>(command.get())) + return module_command->module; } return nullptr; } @@ -205,9 +207,8 @@ const Module* Script::GetModule(const Var& var) const { Index index = module_bindings.FindIndex(var); if (index >= commands.size()) return nullptr; - const Command& command = *commands[index].get(); - assert(command.type == CommandType::Module); - return command.module; + auto* command = cast<ModuleCommand>(commands[index].get()); + return command->module; } void MakeTypeBindingReverseMapping( @@ -520,55 +521,6 @@ Action::~Action() { } } -Command::Command() : type(CommandType::Module), module(nullptr) {} - -Command::~Command() { - switch (type) { - case CommandType::Module: - delete module; - break; - case CommandType::Action: - delete action; - break; - case CommandType::Register: - destroy_string_slice(®ister_.module_name); - register_.var.~Var(); - break; - case CommandType::AssertMalformed: - delete assert_malformed.module; - destroy_string_slice(&assert_malformed.text); - break; - case CommandType::AssertInvalid: - case CommandType::AssertInvalidNonBinary: - delete assert_invalid.module; - destroy_string_slice(&assert_invalid.text); - break; - case CommandType::AssertUnlinkable: - delete assert_unlinkable.module; - destroy_string_slice(&assert_unlinkable.text); - break; - case CommandType::AssertUninstantiable: - delete assert_uninstantiable.module; - destroy_string_slice(&assert_uninstantiable.text); - break; - case CommandType::AssertReturn: - delete assert_return.action; - delete assert_return.expected; - break; - case CommandType::AssertReturnCanonicalNan: - delete assert_return_arithmetic_nan.action; - break; - case CommandType::AssertReturnArithmeticNan: - delete assert_return_canonical_nan.action; - break; - case CommandType::AssertTrap: - case CommandType::AssertExhaustion: - delete assert_trap.action; - destroy_string_slice(&assert_trap.text); - break; - } -} - Script::Script() {} } // namespace wabt @@ -707,9 +707,6 @@ enum class CommandType { Register, AssertMalformed, AssertInvalid, - /* This is a module that is invalid, but cannot be written as a binary module - * (e.g. it has unresolvable names.) */ - AssertInvalidNonBinary, AssertUnlinkable, AssertUninstantiable, AssertReturn, @@ -723,28 +720,111 @@ enum class CommandType { }; static const int kCommandTypeCount = WABT_ENUM_COUNT(CommandType); -struct Command { +class Command { + public: WABT_DISALLOW_COPY_AND_ASSIGN(Command); - Command(); - ~Command(); + Command() = delete; + virtual ~Command() {} CommandType type; - union { - Module* module; - Action* action; - struct { StringSlice module_name; Var var; } register_; - struct { Action* action; ConstVector* expected; } assert_return; - struct { - Action* action; - } assert_return_canonical_nan, assert_return_arithmetic_nan; - struct { Action* action; StringSlice text; } assert_trap; - struct { - ScriptModule* module; - StringSlice text; - } assert_malformed, assert_invalid, assert_unlinkable, - assert_uninstantiable; - }; + + protected: + explicit Command(CommandType type) : type(type) {} +}; + +template <CommandType TypeEnum> +class CommandMixin : public Command { + public: + static bool classof(const Command* cmd) { return cmd->type == TypeEnum; } + CommandMixin() : Command(TypeEnum) {} +}; + +class ModuleCommand : public CommandMixin<CommandType::Module> { + public: + explicit ModuleCommand(Module* module) : module(module) {} + ~ModuleCommand() { delete module; } + + Module* module; }; + +template <CommandType TypeEnum> +class ActionCommandBase : public CommandMixin<TypeEnum> { + public: + explicit ActionCommandBase(Action* action) : action(action) {} + ~ActionCommandBase() { delete action; } + + Action* action; +}; + +typedef ActionCommandBase<CommandType::Action> ActionCommand; +typedef ActionCommandBase<CommandType::AssertReturnCanonicalNan> + AssertReturnCanonicalNanCommand; +typedef ActionCommandBase<CommandType::AssertReturnArithmeticNan> + AssertReturnArithmeticNanCommand; + +class RegisterCommand : public CommandMixin<CommandType::Register> { + public: + RegisterCommand(StringSlice module_name, const Var& var) + : module_name(module_name), var(var) {} + ~RegisterCommand() { destroy_string_slice(&module_name); } + + StringSlice module_name; + Var var; +}; + +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; +}; + +template <CommandType TypeEnum> +class AssertTrapCommandBase : public CommandMixin<TypeEnum> { + public: + AssertTrapCommandBase(Action* action, StringSlice text) + : action(action), text(text) {} + ~AssertTrapCommandBase() { + delete action; + destroy_string_slice(&text); + } + + Action* action; + StringSlice text; +}; + +typedef AssertTrapCommandBase<CommandType::AssertTrap> AssertTrapCommand; +typedef AssertTrapCommandBase<CommandType::AssertExhaustion> + AssertExhaustionCommand; + +template <CommandType TypeEnum> +class AssertModuleCommand : public CommandMixin<TypeEnum> { + public: + AssertModuleCommand(ScriptModule* module, StringSlice text) + : module(module), text(text) {} + ~AssertModuleCommand() { + delete module; + destroy_string_slice(&text); + } + + ScriptModule* module; + StringSlice text; +}; + +typedef AssertModuleCommand<CommandType::AssertMalformed> + AssertMalformedCommand; +typedef AssertModuleCommand<CommandType::AssertInvalid> AssertInvalidCommand; +typedef AssertModuleCommand<CommandType::AssertUnlinkable> + AssertUnlinkableCommand; +typedef AssertModuleCommand<CommandType::AssertUninstantiable> + AssertUninstantiableCommand; + typedef std::vector<std::unique_ptr<Command>> CommandPtrVector; struct Script { diff --git a/src/prebuilt/wast-parser-gen.cc b/src/prebuilt/wast-parser-gen.cc index d1fe2c62..5c34c003 100644 --- a/src/prebuilt/wast-parser-gen.cc +++ b/src/prebuilt/wast-parser-gen.cc @@ -692,9 +692,9 @@ static const yytype_uint16 yyrline[] = 1189, 1197, 1206, 1214, 1220, 1226, 1232, 1238, 1246, 1254, 1264, 1270, 1280, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1301, 1302, 1306, 1311, 1319, 1340, - 1347, 1350, 1358, 1376, 1384, 1395, 1406, 1417, 1423, 1429, - 1435, 1441, 1447, 1452, 1457, 1463, 1472, 1477, 1478, 1483, - 1493, 1497, 1504, 1516, 1517, 1524, 1527, 1587, 1599 + 1347, 1350, 1358, 1376, 1384, 1395, 1406, 1417, 1420, 1423, + 1426, 1429, 1432, 1435, 1438, 1441, 1447, 1450, 1451, 1454, + 1462, 1466, 1473, 1485, 1486, 1493, 1496, 1560, 1569 }; #endif @@ -4201,153 +4201,122 @@ yyreduce: case 197: #line 1417 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertMalformed; - (yyval.command)->assert_malformed.module = (yyvsp[-2].script_module); - (yyval.command)->assert_malformed.text = (yyvsp[-1].text); + (yyval.command) = new AssertMalformedCommand((yyvsp[-2].script_module), (yyvsp[-1].text)); } -#line 4210 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4207 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 198: -#line 1423 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1420 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertInvalid; - (yyval.command)->assert_invalid.module = (yyvsp[-2].script_module); - (yyval.command)->assert_invalid.text = (yyvsp[-1].text); + (yyval.command) = new AssertInvalidCommand((yyvsp[-2].script_module), (yyvsp[-1].text)); } -#line 4221 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4215 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 199: -#line 1429 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1423 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertUnlinkable; - (yyval.command)->assert_unlinkable.module = (yyvsp[-2].script_module); - (yyval.command)->assert_unlinkable.text = (yyvsp[-1].text); + (yyval.command) = new AssertUnlinkableCommand((yyvsp[-2].script_module), (yyvsp[-1].text)); } -#line 4232 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4223 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 200: -#line 1435 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1426 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertUninstantiable; - (yyval.command)->assert_uninstantiable.module = (yyvsp[-2].script_module); - (yyval.command)->assert_uninstantiable.text = (yyvsp[-1].text); + (yyval.command) = new AssertUninstantiableCommand((yyvsp[-2].script_module), (yyvsp[-1].text)); } -#line 4243 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4231 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 201: -#line 1441 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1429 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertReturn; - (yyval.command)->assert_return.action = (yyvsp[-2].action); - (yyval.command)->assert_return.expected = (yyvsp[-1].consts); + (yyval.command) = new AssertReturnCommand((yyvsp[-2].action), (yyvsp[-1].consts)); } -#line 4254 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4239 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 202: -#line 1447 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1432 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertReturnCanonicalNan; - (yyval.command)->assert_return_canonical_nan.action = (yyvsp[-1].action); + (yyval.command) = new AssertReturnCanonicalNanCommand((yyvsp[-1].action)); } -#line 4264 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4247 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 203: -#line 1452 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1435 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertReturnArithmeticNan; - (yyval.command)->assert_return_arithmetic_nan.action = (yyvsp[-1].action); + (yyval.command) = new AssertReturnArithmeticNanCommand((yyvsp[-1].action)); } -#line 4274 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4255 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 204: -#line 1457 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1438 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertTrap; - (yyval.command)->assert_trap.action = (yyvsp[-2].action); - (yyval.command)->assert_trap.text = (yyvsp[-1].text); + (yyval.command) = new AssertTrapCommand((yyvsp[-2].action), (yyvsp[-1].text)); } -#line 4285 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4263 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 205: -#line 1463 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1441 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::AssertExhaustion; - (yyval.command)->assert_trap.action = (yyvsp[-2].action); - (yyval.command)->assert_trap.text = (yyvsp[-1].text); + (yyval.command) = new AssertExhaustionCommand((yyvsp[-2].action), (yyvsp[-1].text)); } -#line 4296 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4271 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 206: -#line 1472 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1447 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::Action; - (yyval.command)->action = (yyvsp[0].action); + (yyval.command) = new ActionCommand((yyvsp[0].action)); } -#line 4306 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4279 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 208: -#line 1478 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1451 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::Module; - (yyval.command)->module = (yyvsp[0].module); + (yyval.command) = new ModuleCommand((yyvsp[0].module)); } -#line 4316 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4287 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 209: -#line 1483 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1454 "src/wast-parser.y" /* yacc.c:1646 */ { - (yyval.command) = new Command(); - (yyval.command)->type = CommandType::Register; - (yyval.command)->register_.module_name = (yyvsp[-2].text); - (yyval.command)->register_.var = std::move(*(yyvsp[-1].var)); + auto* command = new RegisterCommand((yyvsp[-2].text), *(yyvsp[-1].var)); delete (yyvsp[-1].var); - (yyval.command)->register_.var.loc = (yylsp[-1]); + command->var.loc = (yylsp[-1]); + (yyval.command) = command; } -#line 4329 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4298 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 210: -#line 1493 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1462 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.commands) = new CommandPtrVector(); (yyval.commands)->emplace_back((yyvsp[0].command)); } -#line 4338 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4307 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 211: -#line 1497 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1466 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.commands) = (yyvsp[-1].commands); (yyval.commands)->emplace_back((yyvsp[0].command)); } -#line 4347 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4316 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 212: -#line 1504 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1473 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.const_).loc = (yylsp[-2]); if (WABT_FAILED(parse_const((yyvsp[-2].type), (yyvsp[-1].literal).type, (yyvsp[-1].literal).text.start, @@ -4358,34 +4327,34 @@ yyreduce: } delete [] (yyvsp[-1].literal).text.start; } -#line 4362 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4331 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 213: -#line 1516 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1485 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.consts) = new ConstVector(); } -#line 4368 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4337 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 214: -#line 1517 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1486 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.consts) = (yyvsp[-1].consts); (yyval.consts)->push_back((yyvsp[0].const_)); } -#line 4377 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4346 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 215: -#line 1524 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1493 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.script) = new Script(); } -#line 4385 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4354 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 216: -#line 1527 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1496 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.script) = new Script(); (yyval.script)->commands = std::move(*(yyvsp[0].commands)); @@ -4393,14 +4362,14 @@ yyreduce: int last_module_index = -1; for (size_t i = 0; i < (yyval.script)->commands.size(); ++i) { - Command& command = *(yyval.script)->commands[i].get(); + Command* command = (yyval.script)->commands[i].get(); Var* module_var = nullptr; - switch (command.type) { + switch (command->type) { case CommandType::Module: { last_module_index = i; - /* Wire up module name bindings. */ - Module* module = command.module; + // Wire up module name bindings. + Module* module = cast<ModuleCommand>(command)->module; if (module->name.length == 0) continue; @@ -4410,25 +4379,29 @@ yyreduce: } case CommandType::AssertReturn: - module_var = &command.assert_return.action->module_var; + module_var = + &cast<AssertReturnCommand>(command)->action->module_var; goto has_module_var; case CommandType::AssertReturnCanonicalNan: - module_var = - &command.assert_return_canonical_nan.action->module_var; + module_var = &cast<AssertReturnCanonicalNanCommand>(command) + ->action->module_var; goto has_module_var; case CommandType::AssertReturnArithmeticNan: - module_var = - &command.assert_return_arithmetic_nan.action->module_var; + module_var = &cast<AssertReturnArithmeticNanCommand>(command) + ->action->module_var; goto has_module_var; case CommandType::AssertTrap: + module_var = &cast<AssertTrapCommand>(command)->action->module_var; + goto has_module_var; case CommandType::AssertExhaustion: - module_var = &command.assert_trap.action->module_var; + module_var = + &cast<AssertExhaustionCommand>(command)->action->module_var; goto has_module_var; case CommandType::Action: - module_var = &command.action->module_var; + module_var = &cast<ActionCommand>(command)->action->module_var; goto has_module_var; case CommandType::Register: - module_var = &command.register_.var; + module_var = &cast<RegisterCommand>(command)->var; goto has_module_var; has_module_var: { @@ -4446,29 +4419,26 @@ yyreduce: } } } -#line 4450 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4423 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 217: -#line 1587 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1560 "src/wast-parser.y" /* yacc.c:1646 */ { (yyval.script) = new Script(); - Command* command = new Command(); - command->type = CommandType::Module; - command->module = (yyvsp[0].module); - (yyval.script)->commands.emplace_back(command); + (yyval.script)->commands.emplace_back(new ModuleCommand((yyvsp[0].module))); } -#line 4462 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4432 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; case 218: -#line 1599 "src/wast-parser.y" /* yacc.c:1646 */ +#line 1569 "src/wast-parser.y" /* yacc.c:1646 */ { parser->script = (yyvsp[0].script); } -#line 4468 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4438 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ break; -#line 4472 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ +#line 4442 "src/prebuilt/wast-parser-gen.cc" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -4703,7 +4673,7 @@ yyreturn: #endif return yyresult; } -#line 1602 "src/wast-parser.y" /* yacc.c:1906 */ +#line 1572 "src/wast-parser.y" /* yacc.c:1906 */ void append_expr_list(ExprList* expr_list, ExprList* expr) { diff --git a/src/resolve-names.cc b/src/resolve-names.cc index e7090f59..e6e29194 100644 --- a/src/resolve-names.cc +++ b/src/resolve-names.cc @@ -19,6 +19,7 @@ #include <cassert> #include <cstdio> +#include "cast.h" #include "expr-visitor.h" #include "ir.h" #include "wast-parser-lexer-shared.h" @@ -404,7 +405,7 @@ void NameResolver::VisitScriptModule(ScriptModule* script_module) { void NameResolver::VisitCommand(Command* command) { switch (command->type) { case CommandType::Module: - VisitModule(command->module); + VisitModule(cast<ModuleCommand>(command)->module); break; case CommandType::Action: @@ -424,31 +425,22 @@ void NameResolver::VisitCommand(Command* command) { break; case CommandType::AssertInvalid: { + auto* assert_invalid_command = cast<AssertInvalidCommand>(command); /* The module may be invalid because the names cannot be resolved; we * don't want to print errors or fail if that's the case, but we still * should try to resolve names when possible. */ SourceErrorHandlerNop new_error_handler; - NameResolver new_resolver(lexer_, script_, &new_error_handler); - new_resolver.VisitScriptModule(command->assert_invalid.module); - if (WABT_FAILED(new_resolver.result_)) { - command->type = CommandType::AssertInvalidNonBinary; - } + new_resolver.VisitScriptModule(assert_invalid_command->module); break; } - case CommandType::AssertInvalidNonBinary: - /* The only reason a module would be "non-binary" is if the names cannot - * be resolved. So we assume name resolution has already been tried and - * failed, so skip it. */ - break; - case CommandType::AssertUnlinkable: - VisitScriptModule(command->assert_unlinkable.module); + VisitScriptModule(cast<AssertUnlinkableCommand>(command)->module); break; case CommandType::AssertUninstantiable: - VisitScriptModule(command->assert_uninstantiable.module); + VisitScriptModule(cast<AssertUninstantiableCommand>(command)->module); break; } } diff --git a/src/validator.cc b/src/validator.cc index 8084a85c..6c4183ec 100644 --- a/src/validator.cc +++ b/src/validator.cc @@ -1080,35 +1080,35 @@ void Validator::CheckAssertReturnNanCommand(const Action* action) { void Validator::CheckCommand(const Command* command) { switch (command->type) { case CommandType::Module: - CheckModule(command->module); + CheckModule(cast<ModuleCommand>(command)->module); break; case CommandType::Action: // Ignore result type. - CheckAction(command->action); + CheckAction(cast<ActionCommand>(command)->action); break; case CommandType::Register: case CommandType::AssertMalformed: case CommandType::AssertInvalid: - case CommandType::AssertInvalidNonBinary: case CommandType::AssertUnlinkable: case CommandType::AssertUninstantiable: // Ignore. break; case CommandType::AssertReturn: { - const Action* action = command->assert_return.action; + auto* assert_return_command = cast<AssertReturnCommand>(command); + const Action* action = assert_return_command->action; ActionResult result = CheckAction(action); switch (result.kind) { case ActionResult::Kind::Types: CheckConstTypes(&action->loc, *result.types, - *command->assert_return.expected, "action"); + *assert_return_command->expected, "action"); break; case ActionResult::Kind::Type: CheckConstType(&action->loc, result.type, - *command->assert_return.expected, "action"); + *assert_return_command->expected, "action"); break; case ActionResult::Kind::Error: @@ -1119,17 +1119,22 @@ void Validator::CheckCommand(const Command* command) { } case CommandType::AssertReturnCanonicalNan: - CheckAssertReturnNanCommand(command->assert_return_canonical_nan.action); + CheckAssertReturnNanCommand( + cast<AssertReturnCanonicalNanCommand>(command)->action); break; case CommandType::AssertReturnArithmeticNan: - CheckAssertReturnNanCommand(command->assert_return_arithmetic_nan.action); + CheckAssertReturnNanCommand( + cast<AssertReturnArithmeticNanCommand>(command)->action); break; case CommandType::AssertTrap: + // ignore result type. + CheckAction(cast<AssertTrapCommand>(command)->action); + break; case CommandType::AssertExhaustion: // ignore result type. - CheckAction(command->assert_trap.action); + CheckAction(cast<AssertExhaustionCommand>(command)->action); break; } } diff --git a/src/wast-parser.y b/src/wast-parser.y index 2303141a..f3c81c08 100644 --- a/src/wast-parser.y +++ b/src/wast-parser.y @@ -1415,78 +1415,47 @@ action : assertion : LPAR ASSERT_MALFORMED script_module quoted_text RPAR { - $$ = new Command(); - $$->type = CommandType::AssertMalformed; - $$->assert_malformed.module = $3; - $$->assert_malformed.text = $4; + $$ = new AssertMalformedCommand($3, $4); } | LPAR ASSERT_INVALID script_module quoted_text RPAR { - $$ = new Command(); - $$->type = CommandType::AssertInvalid; - $$->assert_invalid.module = $3; - $$->assert_invalid.text = $4; + $$ = new AssertInvalidCommand($3, $4); } | LPAR ASSERT_UNLINKABLE script_module quoted_text RPAR { - $$ = new Command(); - $$->type = CommandType::AssertUnlinkable; - $$->assert_unlinkable.module = $3; - $$->assert_unlinkable.text = $4; + $$ = new AssertUnlinkableCommand($3, $4); } | LPAR ASSERT_TRAP script_module quoted_text RPAR { - $$ = new Command(); - $$->type = CommandType::AssertUninstantiable; - $$->assert_uninstantiable.module = $3; - $$->assert_uninstantiable.text = $4; + $$ = new AssertUninstantiableCommand($3, $4); } | LPAR ASSERT_RETURN action const_list RPAR { - $$ = new Command(); - $$->type = CommandType::AssertReturn; - $$->assert_return.action = $3; - $$->assert_return.expected = $4; + $$ = new AssertReturnCommand($3, $4); } | LPAR ASSERT_RETURN_CANONICAL_NAN action RPAR { - $$ = new Command(); - $$->type = CommandType::AssertReturnCanonicalNan; - $$->assert_return_canonical_nan.action = $3; + $$ = new AssertReturnCanonicalNanCommand($3); } | LPAR ASSERT_RETURN_ARITHMETIC_NAN action RPAR { - $$ = new Command(); - $$->type = CommandType::AssertReturnArithmeticNan; - $$->assert_return_arithmetic_nan.action = $3; + $$ = new AssertReturnArithmeticNanCommand($3); } | LPAR ASSERT_TRAP action quoted_text RPAR { - $$ = new Command(); - $$->type = CommandType::AssertTrap; - $$->assert_trap.action = $3; - $$->assert_trap.text = $4; + $$ = new AssertTrapCommand($3, $4); } | LPAR ASSERT_EXHAUSTION action quoted_text RPAR { - $$ = new Command(); - $$->type = CommandType::AssertExhaustion; - $$->assert_trap.action = $3; - $$->assert_trap.text = $4; + $$ = new AssertExhaustionCommand($3, $4); } ; cmd : action { - $$ = new Command(); - $$->type = CommandType::Action; - $$->action = $1; + $$ = new ActionCommand($1); } | assertion | module { - $$ = new Command(); - $$->type = CommandType::Module; - $$->module = $1; + $$ = new ModuleCommand($1); } | LPAR REGISTER quoted_text script_var_opt RPAR { - $$ = new Command(); - $$->type = CommandType::Register; - $$->register_.module_name = $3; - $$->register_.var = std::move(*$4); + auto* command = new RegisterCommand($3, *$4); delete $4; - $$->register_.var.loc = @4; + command->var.loc = @4; + $$ = command; } ; cmd_list : @@ -1531,14 +1500,14 @@ script : int last_module_index = -1; for (size_t i = 0; i < $$->commands.size(); ++i) { - Command& command = *$$->commands[i].get(); + Command* command = $$->commands[i].get(); Var* module_var = nullptr; - switch (command.type) { + switch (command->type) { case CommandType::Module: { last_module_index = i; - /* Wire up module name bindings. */ - Module* module = command.module; + // Wire up module name bindings. + Module* module = cast<ModuleCommand>(command)->module; if (module->name.length == 0) continue; @@ -1548,25 +1517,29 @@ script : } case CommandType::AssertReturn: - module_var = &command.assert_return.action->module_var; + module_var = + &cast<AssertReturnCommand>(command)->action->module_var; goto has_module_var; case CommandType::AssertReturnCanonicalNan: - module_var = - &command.assert_return_canonical_nan.action->module_var; + module_var = &cast<AssertReturnCanonicalNanCommand>(command) + ->action->module_var; goto has_module_var; case CommandType::AssertReturnArithmeticNan: - module_var = - &command.assert_return_arithmetic_nan.action->module_var; + module_var = &cast<AssertReturnArithmeticNanCommand>(command) + ->action->module_var; goto has_module_var; case CommandType::AssertTrap: + module_var = &cast<AssertTrapCommand>(command)->action->module_var; + goto has_module_var; case CommandType::AssertExhaustion: - module_var = &command.assert_trap.action->module_var; + module_var = + &cast<AssertExhaustionCommand>(command)->action->module_var; goto has_module_var; case CommandType::Action: - module_var = &command.action->module_var; + module_var = &cast<ActionCommand>(command)->action->module_var; goto has_module_var; case CommandType::Register: - module_var = &command.register_.var; + module_var = &cast<RegisterCommand>(command)->var; goto has_module_var; has_module_var: { @@ -1586,10 +1559,7 @@ script : } | inline_module { $$ = new Script(); - Command* command = new Command(); - command->type = CommandType::Module; - command->module = $1; - $$->commands.emplace_back(command); + $$->commands.emplace_back(new ModuleCommand($1)); } ; |