Skip to content

Commit

Permalink
[spectest] Implement module instance command (#214 from titzer/specte…
Browse files Browse the repository at this point in the history
…st_instance)
  • Loading branch information
titzer authored Oct 25, 2024
2 parents 42b2dfa + 039e4e6 commit 5aa3b5c
Show file tree
Hide file tree
Showing 6 changed files with 345 additions and 77 deletions.
14 changes: 14 additions & 0 deletions test/regress/core/instance.bin.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(module definition $M binary
"\00\61\73\6d\01\00\00\00\01\89\80\80\80\00\02\60"
"\00\01\7f\60\01\7f\00\03\83\80\80\80\00\02\00\01"
"\06\86\80\80\80\00\01\7f\01\41\00\0b\07\94\80\80"
"\80\00\03\04\67\6c\6f\62\03\00\03\67\65\74\00\00"
"\03\73\65\74\00\01\0a\95\80\80\80\00\02\84\80\80"
"\80\00\00\23\00\0b\86\80\80\80\00\00\20\00\24\00"
"\0b"
)
(module instance $I1 $M)
(module instance $I2 $M)
(register "I1" $I1)
(register "I2" $I2)
(assert_return (invoke $I1 "set" (i32.const 0x1)))
14 changes: 14 additions & 0 deletions test/regress/core/instance.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
;; Instantiation is generative

(module definition $M
(global (export "glob") (mut i32) (i32.const 0))
(func (export "get") (result i32) (global.get 0))
(func (export "set") (param i32) (global.set 0 (local.get 0)))
)

(module instance $I1 $M)
(module instance $I2 $M)
(register "I1" $I1)
(register "I2" $I2)

(assert_return (invoke $I1 "set" (i32.const 1)))
170 changes: 170 additions & 0 deletions test/regress/wasm-3.0/instance.wast
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
;; Instantiation is generative

(module definition $M
(global (export "glob") (mut i32) (i32.const 0))
(table (export "tab") 10 funcref (ref.null func))
(memory (export "mem") 1)
(tag (export "tag"))
)

(module instance $I1 $M)
(module instance $I2 $M)
(register "I1" $I1)
(register "I2" $I2)

(module
(import "I1" "glob" (global $glob1 (mut i32)))
(import "I2" "glob" (global $glob2 (mut i32)))
(import "I1" "tab" (table $tab1 10 funcref))
(import "I2" "tab" (table $tab2 10 funcref))
(import "I1" "mem" (memory $mem1 1))
(import "I2" "mem" (memory $mem2 1))
(import "I1" "tag" (tag $tag1))
(import "I2" "tag" (tag $tag2))

(func $f)
(elem declare func $f)

(func (export "glob") (result i32)
(global.set $glob1 (i32.const 1))
(global.get $glob2)
)
(func (export "tab") (result funcref)
(table.set $tab1 (i32.const 0) (ref.func $f))
(table.get $tab2 (i32.const 0))
)
(func (export "mem") (result i32)
(i32.store $mem1 (i32.const 0) (i32.const 1))
(i32.load $mem2 (i32.const 0))
)
(func (export "tag") (result i32)
(block $on_tag1
(block $on_other
(try_table (catch $tag1 $on_tag1) (catch_all $on_other)
(throw $tag2)
)
(unreachable)
)
(return (i32.const 0))
)
(return (i32.const 1))
)
)

(assert_return (invoke "glob") (i32.const 0))
(assert_return (invoke "tab") (ref.null))
(assert_return (invoke "mem") (i32.const 0))
(assert_return (invoke "tag") (i32.const 0))


;; Import is not generative

(module
(import "I1" "glob" (global $glob1 (mut i32)))
(import "I1" "glob" (global $glob2 (mut i32)))
(import "I1" "tab" (table $tab1 10 funcref))
(import "I1" "tab" (table $tab2 10 funcref))
(import "I1" "mem" (memory $mem1 1))
(import "I1" "mem" (memory $mem2 1))
(import "I1" "tag" (tag $tag1))
(import "I1" "tag" (tag $tag2))

(func $f)
(elem declare func $f)

(func (export "glob") (result i32)
(global.set $glob1 (i32.const 1))
(global.get $glob2)
)
(func (export "tab") (result funcref)
(table.set $tab1 (i32.const 0) (ref.func $f))
(table.get $tab2 (i32.const 0))
)
(func (export "mem") (result i32)
(i32.store $mem1 (i32.const 0) (i32.const 1))
(i32.load $mem2 (i32.const 0))
)
(func (export "tag") (result i32)
(block $on_tag1
(block $on_other
(try_table (catch $tag1 $on_tag1) (catch_all $on_other)
(throw $tag2)
)
(unreachable)
)
(return (i32.const 0))
)
(return (i32.const 1))
)
)

(assert_return (invoke "glob") (i32.const 1))
(assert_return (invoke "tab") (ref.func))
(assert_return (invoke "mem") (i32.const 1))
(assert_return (invoke "tag") (i32.const 1))


;; Export is not generative

(module definition $N
(global $glob (mut i32) (i32.const 0))
(table $tab 10 funcref (ref.null func))
(memory $mem 1)
(tag $tag)

(export "glob1" (global $glob))
(export "glob2" (global $glob))
(export "tab1" (table $tab))
(export "tab2" (table $tab))
(export "mem1" (memory $mem))
(export "mem2" (memory $mem))
(export "tag1" (tag $tag))
(export "tag2" (tag $tag))
)

(module instance $I $N)
(register "I" $I)

(module
(import "I" "glob1" (global $glob1 (mut i32)))
(import "I" "glob2" (global $glob2 (mut i32)))
(import "I" "tab1" (table $tab1 10 funcref))
(import "I" "tab2" (table $tab2 10 funcref))
(import "I" "mem1" (memory $mem1 1))
(import "I" "mem2" (memory $mem2 1))
(import "I" "tag1" (tag $tag1))
(import "I" "tag2" (tag $tag2))

(func $f)
(elem declare func $f)

(func (export "glob") (result i32)
(global.set $glob1 (i32.const 1))
(global.get $glob2)
)
(func (export "tab") (result funcref)
(table.set $tab1 (i32.const 0) (ref.func $f))
(table.get $tab2 (i32.const 0))
)
(func (export "mem") (result i32)
(i32.store $mem1 (i32.const 0) (i32.const 1))
(i32.load $mem2 (i32.const 0))
)
(func (export "tag") (result i32)
(block $on_tag1
(block $on_other
(try_table (catch $tag1 $on_tag1) (catch_all $on_other)
(throw $tag2)
)
(unreachable)
)
(return (i32.const 0))
)
(return (i32.const 1))
)
)

(assert_return (invoke "glob") (i32.const 1))
(assert_return (invoke "tab") (ref.func))
(assert_return (invoke "mem") (i32.const 1))
(assert_return (invoke "tag") (i32.const 1))
112 changes: 77 additions & 35 deletions test/unittest/SpecTestParserTest.v3
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,15 @@ def X_ = void(
T("stringu", test_stringu),
T("stringun", test_stringun),
T("modbin1", test_modbin1),
T("moddefbin1", test_moddefbin1),
T("modbinx", test_modbinx),
T("modquote1", test_modquote1),
T("modquotex", test_modquotex),
T("modx", test_modx),
T("mod_named", test_mod_named),
T("mod_def", test_mod_def),
T("moddef", test_moddef),
T("moddef_named", test_moddef_named),
T("modinst", test_modinst),
T("invoke1", test_invoke1),
T("invokex", test_invokex),
T("invoke_named", test_invoke_named),
Expand Down Expand Up @@ -95,16 +98,23 @@ class SpecTestParserTester(t: Tester) {
return false;
}
match (expected) {
Binary(varname, bytes) => {
Binary(isdef, varname, bytes) => {
var that = StModule.Binary.!(got);
t.assertz(isdef, that.isdef);
t.assert_string(varname, that.varname);
t.assert_string(bytes, that.bytes);
}
Quote(varname, source) => {
Quote(isdef, varname, source) => {
var that = StModule.Quote.!(got);
t.assertz(isdef, that.isdef);
t.assert_string(varname, that.varname);
t.assert_string(source, that.source);
}
Instance(instname, modname) => {
var that = StModule.Instance.!(got);
t.assert_string(instname, that.instname);
t.assert_string(modname, that.modname);
}
}
return true;
}
Expand Down Expand Up @@ -253,17 +263,23 @@ class SpecTestParserTester(t: Tester) {
else t.fail1("expected error, got %s", c.cmd.name);
}
}
def assert_bin(input: string, expected_varname: string, expected_bytes: Array<byte>) {
def assert_bin(input: string, expected_isdef: bool, expected_varname: string, expected_bytes: Array<byte>) {
var c = parseCommand(input);
if (c == null) return t.fail("expected binary module, but got error");
var exp = StCommand.Module(StModule.Binary(expected_varname,
var exp = StCommand.Module(StModule.Binary(expected_isdef, expected_varname,
expected_bytes));
assert_cmd(exp, c.cmd);
}
def assert_quote(input: string, expected_varname: string, expected_source: string) {
def assert_inst(input: string, expected_instname: string, expected_modname: string) {
var c = parseCommand(input);
if (c == null) return t.fail("expected module instance, but got error");
var exp = StCommand.Module(StModule.Instance(expected_instname, expected_modname));
assert_cmd(exp, c.cmd);
}
def assert_quote(input: string, expected_isdef: bool, expected_varname: string, expected_source: string) {
var c = parseCommand(input);
if (c == null) return t.fail("expected quote module, but got error");
var exp = StCommand.Module(StModule.Quote(expected_varname,
var exp = StCommand.Module(StModule.Quote(expected_isdef, expected_varname,
expected_source));
assert_cmd(exp, c.cmd);
}
Expand Down Expand Up @@ -863,13 +879,23 @@ def test_stringun(t: SpecTestParserTester) {
}

def test_modbin1(t: SpecTestParserTester) {
t.assert_bin("(module binary \"\")", null, []);
t.assert_bin("(module binary \"\\EF\")", null, [0xEF]);
t.assert_bin("(module binary \"\\01\\02\\03\")", null, [0x01, 0x02, 0x03]);
t.assert_bin("(module binary \"\\AA\" \"\\BB\" \"\\CC\")", null, [0xAA, 0xBB, 0xCC]);
t.assert_bin("(module binary \"\\22\"\n\"\\33\"\n\"\\44\"\n)", null, [0x22, 0x33, 0x44]);
t.assert_bin("(module binary)", null, []);
t.assert_bin("(module binary )", null, []);
t.assert_bin("(module binary \"\")", false, null, []);
t.assert_bin("(module binary \"\\EF\")", false, null, [0xEF]);
t.assert_bin("(module binary \"\\01\\02\\03\")", false, null, [0x01, 0x02, 0x03]);
t.assert_bin("(module binary \"\\AA\" \"\\BB\" \"\\CC\")", false, null, [0xAA, 0xBB, 0xCC]);
t.assert_bin("(module binary \"\\22\"\n\"\\33\"\n\"\\44\"\n)", false, null, [0x22, 0x33, 0x44]);
t.assert_bin("(module binary)", false, null, []);
t.assert_bin("(module binary )", false, null, []);
}

def test_moddefbin1(t: SpecTestParserTester) {
t.assert_bin("(module definition binary \"\")", true, null, []);
t.assert_bin("(module definition binary \"\\EF\")", true, null, [0xEF]);
t.assert_bin("(module definition binary \"\\01\\02\\03\")", true, null, [0x01, 0x02, 0x03]);
t.assert_bin("(module definition binary \"\\AA\" \"\\BB\" \"\\CC\")", true, null, [0xAA, 0xBB, 0xCC]);
t.assert_bin("(module definition binary \"\\22\"\n\"\\33\"\n\"\\44\"\n)", true, null, [0x22, 0x33, 0x44]);
t.assert_bin("(module definition binary)", true, null, []);
t.assert_bin("(module definition binary )", true, null, []);
}

def test_modbinx(t: SpecTestParserTester) {
Expand All @@ -881,10 +907,10 @@ def test_modbinx(t: SpecTestParserTester) {
}

def test_modquote1(t: SpecTestParserTester) {
t.assert_quote("(module quote \"\")", null, "");
t.assert_quote("(module quote \"(module foo)\")", null, "(module foo)");
t.assert_quote("(module quote \"(module\" \" foo)\")", null, "(module foo)");
t.assert_quote("(module quote \"(module\"\n\" foo)\")", null, "(module foo)");
t.assert_quote("(module quote \"\")", false, null, "");
t.assert_quote("(module quote \"(module foo)\")", false, null, "(module foo)");
t.assert_quote("(module quote \"(module\" \" foo)\")", false, null, "(module foo)");
t.assert_quote("(module quote \"(module\"\n\" foo)\")", false, null, "(module foo)");
}

def test_modquotex(t: SpecTestParserTester) {
Expand All @@ -906,15 +932,27 @@ def test_modx(t: SpecTestParserTester) {
}

def test_mod_named(t: SpecTestParserTester) {
t.assert_bin("(module $f binary \"\")", "$f", []);
t.assert_bin("(module $az_09_AZ binary \"\")", "$az_09_AZ", []);
t.assert_quote("(module $__ quote \"(foo)\")", "$__", "(foo)");
t.assert_bin("(module $f binary \"\")", false, "$f", []);
t.assert_bin("(module $az_09_AZ binary \"\")", false, "$az_09_AZ", []);
t.assert_quote("(module $__ quote \"(foo)\")", false, "$__", "(foo)");
}

def test_mod_def(t: SpecTestParserTester) {
t.assert_bin("(module definition $f binary \"\")", "$f", []);
// t.assert_bin("(module definition $az_09_AZ binary \"\")", "$az_09_AZ", []);
// t.assert_quote("(module definition $__ quote \"(foo)\")", "$__", "(foo)");
def test_moddef(t: SpecTestParserTester) {
t.assert_bin("(module definition $f binary \"\")", true, "$f", []);
t.assert_bin("(module definition $az_09_AZ binary \"\")", true, "$az_09_AZ", []);
t.assert_quote("(module definition $__ quote \"(foo)\")", true, "$__", "(foo)");
}

def test_moddef_named(t: SpecTestParserTester) {
t.assert_bin("(module $f binary \"\")", false, "$f", []);
t.assert_bin("(module $az_09_AZ binary \"\")", false, "$az_09_AZ", []);
t.assert_quote("(module $__ quote \"(foo)\")", false, "$__", "(foo)");
}

def test_modinst(t: SpecTestParserTester) {
t.assert_inst("(module instance)", null, null);
t.assert_inst("(module instance $az)", "$az", null);
t.assert_inst("(module instance $__ $_f)", "$__", "$_f");
}

def test_invoke1(t: SpecTestParserTester) {
Expand Down Expand Up @@ -993,9 +1031,9 @@ def testActionCommand(t: SpecTestParserTester, pat: string,
}

def MODULE_CASES = [
("(module binary \"\")", StModule.Binary(null, [])),
("(module $f binary \"\")", StModule.Binary("$f", [])),
("(module $g binary \"\\6E\\AA\")", StModule.Binary("$g", [0x6E, 0xAA]))
("(module binary \"\")", StModule.Binary(false, null, [])),
("(module $f binary \"\")", StModule.Binary(false, "$f", [])),
("(module $g binary \"\\6E\\AA\")", StModule.Binary(false, "$g", [0x6E, 0xAA]))
];
def testModuleCommand(t: SpecTestParserTester, pat: string,
make: StModule -> StCommand) {
Expand Down Expand Up @@ -1086,7 +1124,7 @@ def test_assert_malformedx(t: SpecTestParserTester) {
}

def test_assert_malformed(t: SpecTestParserTester) {
t.assert_cmds(StCommand.AssertMalformed(StModule.Quote(null, "source"), "msg1"),
t.assert_cmds(StCommand.AssertMalformed(StModule.Quote(false, null, "source"), "msg1"),
"(assert_malformed (module quote \"source\") \"msg1\")");

}
Expand Down Expand Up @@ -1172,12 +1210,16 @@ def test_comment(t: SpecTestParserTester) {
t.assert_i("(i32.const ;f \n \n 0)", 0);
t.assert_i("(i32.const ;abcdzABCD!@`~#$%^&*()-_=+[{]}:,<.>/?\n0)", 0);

t.assert_bin("(module binary \"\")", null, []);
t.assert_bin("(;C\n module binary \"\")", null, []);
t.assert_bin("(module ;C\n binary \"\")", null, []);
t.assert_bin("(module binary ;C\n \"\")", null, []);
t.assert_bin("(module binary \"\" ;C\n )", null, []);
t.assert_bin("(module binary \"\" );C\n ", null, []);
t.assert_bin("(module binary \"\")", false, null, []);
t.assert_bin("(;C\n module binary \"\")", false, null, []);
t.assert_bin("(module ;C\n binary \"\")", false, null, []);
t.assert_bin("(module binary ;C\n \"\")", false, null, []);
t.assert_bin("(module binary \"\" ;C\n )", false, null, []);
t.assert_bin("(module binary \"\" );C\n ", false, null, []);

t.assert_bin("(;C\n module definition binary \"\")", true, null, []);
t.assert_bin("(module definition ;C\n binary \"\")", true, null, []);
t.assert_bin("(module definition binary \"\" );C\n ", true, null, []);

t.assert_invoke("(;C\n invoke \"foo\")", null, "foo");
t.assert_invoke("(invoke ;C\n \"foo\")", null, "foo");
Expand Down
Loading

0 comments on commit 5aa3b5c

Please sign in to comment.