Skip to content

Commit 121d68d

Browse files
committed
wast-parser: add support for '(module definition ...)'
WASM v3 spec tests added the '(module definition ...)' construct to WAST. This tells the test runner that the module should not be instantiated immediately. The '(module instance ...)' construct (not yet supported in wabt) instructs the test runner to instantiate the module. This change adds an `is_definition` field to ScriptModule. The field reflects whether the `definition` keyword was encountered after the `module` keyword. When WastParser encounters a TextModule in a script command, it now returns a ScriptModule with the corresponding ScriptTextModule if the module is definition-only.
1 parent ed94ed7 commit 121d68d

File tree

7 files changed

+707
-585
lines changed

7 files changed

+707
-585
lines changed

include/wabt/ir.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1368,6 +1368,8 @@ class ScriptModule {
13681368
ScriptModuleType type() const { return type_; }
13691369
virtual const Location& location() const = 0;
13701370

1371+
bool is_definition = false;
1372+
13711373
protected:
13721374
explicit ScriptModule(ScriptModuleType type) : type_(type) {}
13731375

include/wabt/token.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ WABT_TOKEN(Bin, "bin")
3434
WABT_TOKEN(Item, "item")
3535
WABT_TOKEN(Data, "data")
3636
WABT_TOKEN(Declare, "declare")
37+
WABT_TOKEN(Definition, "definition")
3738
WABT_TOKEN(Delegate, "delegate")
3839
WABT_TOKEN(Do, "do")
3940
WABT_TOKEN(Either, "either")

include/wabt/wast-parser.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class WastParser {
160160
Result Synchronize(SynchronizeFunc);
161161

162162
bool ParseBindVarOpt(std::string* name);
163+
bool ParseDefinitionOpt();
163164
Result ParseVar(Var* out_var);
164165
bool ParseVarOpt(Var* out_var, Var default_var = Var());
165166
Result ParseOffsetExpr(ExprList* out_expr_list);

src/lexer-keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ code, TokenType::Code
4646
data.drop, TokenType::DataDrop, Opcode::DataDrop
4747
data, TokenType::Data
4848
declare, TokenType::Declare
49+
definition, TokenType::Definition
4950
delegate, TokenType::Delegate
5051
do, TokenType::Do
5152
drop, TokenType::Drop, Opcode::Drop

src/prebuilt/lexer-keywords.cc

Lines changed: 656 additions & 581 deletions
Large diffs are not rendered by default.

src/test-wast-parser.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,22 @@ TEST(WastParser, InvalidBinaryModule) {
117117

118118
EXPECT_EQ(expected_data, binary_mod->data);
119119
}
120+
121+
TEST(WastParser, ModuleDefinition) {
122+
std::string text = "(module definition)";
123+
124+
Errors errors;
125+
auto lexer =
126+
WastLexer::CreateBufferLexer("test", text.c_str(), text.size(), &errors);
127+
Features features;
128+
WastParseOptions options(features);
129+
130+
std::unique_ptr<Script> script;
131+
Result result = ParseWastScript(lexer.get(), &script, &errors, &options);
132+
ASSERT_EQ(result, Result::Ok);
133+
ASSERT_EQ(script->commands.size(), 1U);
134+
Command* cmd = script->commands[0].get();
135+
auto* mod_cmd = cast<ScriptModuleCommand>(cmd);
136+
ASSERT_NE(mod_cmd, nullptr);
137+
ASSERT_TRUE(mod_cmd->script_module->is_definition);
138+
}

src/wast-parser.cc

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,15 @@ bool WastParser::ParseBindVarOpt(std::string* name) {
749749
return true;
750750
}
751751

752+
bool WastParser::ParseDefinitionOpt() {
753+
WABT_TRACE(ParseDefinitionOpt);
754+
if (!PeekMatch(TokenType::Definition)) {
755+
return false;
756+
}
757+
(void)Consume();
758+
return true;
759+
}
760+
752761
Result WastParser::ParseVar(Var* out_var) {
753762
WABT_TRACE(ParseVar);
754763
if (PeekMatch(TokenType::Nat)) {
@@ -3664,10 +3673,18 @@ Result WastParser::ParseModuleCommand(Script* script, CommandPtr* out_command) {
36643673

36653674
switch (script_module->type()) {
36663675
case ScriptModuleType::Text: {
3667-
auto command = std::make_unique<ModuleCommand>();
3668-
module = &command->module;
3669-
*module = std::move(cast<TextScriptModule>(script_module.get())->module);
3670-
*out_command = std::move(command);
3676+
if (script_module->is_definition) {
3677+
auto command = std::make_unique<ScriptModuleCommand>();
3678+
module = &command->module;
3679+
*module = std::move(cast<TextScriptModule>(script_module.get())->module);
3680+
command->script_module = std::move(script_module);
3681+
*out_command = std::move(command);
3682+
} else {
3683+
auto command = std::make_unique<ModuleCommand>();
3684+
module = &command->module;
3685+
*module = std::move(cast<TextScriptModule>(script_module.get())->module);
3686+
*out_command = std::move(command);
3687+
}
36713688
break;
36723689
}
36733690

@@ -3852,6 +3869,9 @@ Result WastParser::ParseScriptModule(
38523869
EXPECT(Lpar);
38533870
Location loc = GetLocation();
38543871
EXPECT(Module);
3872+
3873+
bool is_definition = ParseDefinitionOpt();
3874+
38553875
std::string name;
38563876
ParseBindVarOpt(&name);
38573877

@@ -3867,6 +3887,7 @@ Result WastParser::ParseScriptModule(
38673887
bsm->name = name;
38683888
bsm->loc = loc;
38693889
bsm->data = std::move(data);
3890+
bsm->is_definition = is_definition;
38703891
*out_module = std::move(bsm);
38713892
break;
38723893
}
@@ -3882,6 +3903,7 @@ Result WastParser::ParseScriptModule(
38823903
qsm->name = name;
38833904
qsm->loc = loc;
38843905
qsm->data = std::move(data);
3906+
qsm->is_definition = is_definition;
38853907
*out_module = std::move(qsm);
38863908
break;
38873909
}
@@ -3890,6 +3912,7 @@ Result WastParser::ParseScriptModule(
38903912
auto tsm = std::make_unique<TextScriptModule>();
38913913
tsm->module.name = name;
38923914
tsm->module.loc = loc;
3915+
tsm->is_definition = is_definition;
38933916
if (IsModuleField(PeekPair()) || PeekIsCustom()) {
38943917
CHECK_RESULT(ParseModuleFieldList(&tsm->module));
38953918
} else if (!PeekMatch(TokenType::Rpar)) {

0 commit comments

Comments
 (0)