summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/binary-writer-spec.cc126
-rw-r--r--src/ir.cc60
-rw-r--r--src/ir.h122
-rw-r--r--src/prebuilt/wast-parser-gen.cc184
-rw-r--r--src/resolve-names.cc20
-rw-r--r--src/validator.cc23
-rw-r--r--src/wast-parser.y92
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("}");
diff --git a/src/ir.cc b/src/ir.cc
index 52db44cf..7b09e3c4 100644
--- a/src/ir.cc
+++ b/src/ir.cc
@@ -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(&register_.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
diff --git a/src/ir.h b/src/ir.h
index 55d0f380..d4b12001 100644
--- a/src/ir.h
+++ b/src/ir.h
@@ -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));
}
;