Repository: tetratelabs/wazero
Pull request #439 (2022-04-05 01:43:42)

wat: syncs spectest with latest text decoder
This helps us prioritize text format features

codefromthecrypt: thanks for the link. I noticed we exported an unused global so removed it.

Patch:
diff --git a/api/wasm.go b/api/wasm.go
index 9a6e25fa..408d4d09 100644
--- a/api/wasm.go
+++ b/api/wasm.go
@@ -11,8 +11,8 @@ import (
 // only definable as a value type.
 //
 // The following describes how to convert between Wasm and Golang types:
-//  * ValueTypeI32 - uint64(uint32,int32,int64)
-//  * ValueTypeI64 - uint64
+//  * ValueTypeI32 - uint64(uint32,int32)
+//  * ValueTypeI64 - uint64(int64)
 //  * ValueTypeF32 - EncodeF32 DecodeF32 from float32
 //  * ValueTypeF64 - EncodeF64 DecodeF64 from float64
 //
diff --git a/internal/wasm/text/func_parser.go b/internal/wasm/text/func_parser.go
index 5503a3ff..e24f0068 100644
--- a/internal/wasm/text/func_parser.go
+++ b/internal/wasm/text/func_parser.go
@@ -145,15 +145,15 @@ func (p *funcParser) beginFieldOrInstruction(tok tokenType, tokenBytes []byte, _
 func (p *funcParser) beginInstruction(tokenBytes []byte) (next tokenParser, err error) {
 	var opCode wasm.Opcode
 	switch string(tokenBytes) {
-	case "local.get": // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefsyntax-instr-variablemathsflocalgetx%E2%91%A0
-		opCode = wasm.OpcodeLocalGet
-		next = p.parseLocalIndex
-	case "i32.add": // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-instr-numeric
-		opCode = wasm.OpcodeI32Add
-		next = p.beginFieldOrInstruction
 	case "call": // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefsyntax-instr-controlmathsfcallx
 		opCode = wasm.OpcodeCall
 		next = p.parseFuncIndex
+	case "drop": // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefsyntax-instr-parametricmathsfdrop
+		opCode = wasm.OpcodeDrop
+		next = p.beginFieldOrInstruction
+	case "i32.add": // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-instr-numeric
+		opCode = wasm.OpcodeI32Add
+		next = p.beginFieldOrInstruction
 	case "i32.extend8_s": // See https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md
 		opCode = wasm.OpcodeI32Extend8S
 		next = p.beginFieldOrInstruction
@@ -169,6 +169,9 @@ func (p *funcParser) beginInstruction(tokenBytes []byte) (next tokenParser, err
 	case "i64.extend32_s": // See https://github.com/WebAssembly/spec/blob/main/proposals/sign-extension-ops/Overview.md
 		opCode = wasm.OpcodeI64Extend32S
 		next = p.beginFieldOrInstruction
+	case "local.get": // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#-hrefsyntax-instr-variablemathsflocalgetx%E2%91%A0
+		opCode = wasm.OpcodeLocalGet
+		next = p.parseLocalIndex
 	default:
 		return nil, fmt.Errorf("unsupported instruction: %s", tokenBytes)
 	}


Test patch:
diff --git a/internal/wasm/text/func_parser_test.go b/internal/wasm/text/func_parser_test.go
index 007b8883..1b7241ed 100644
--- a/internal/wasm/text/func_parser_test.go
+++ b/internal/wasm/text/func_parser_test.go
@@ -25,6 +25,11 @@ func TestFuncParser(t *testing.T) {
 			source:   "(func local.get 0)",
 			expected: &wasm.Code{Body: []byte{wasm.OpcodeLocalGet, 0x00, wasm.OpcodeEnd}},
 		},
+		{
+			name:     "local.get, drop",
+			source:   "(func local.get 0 drop)",
+			expected: &wasm.Code{Body: []byte{wasm.OpcodeLocalGet, 0x00, wasm.OpcodeDrop, wasm.OpcodeEnd}},
+		},
 		{
 			name:     "local.get twice",
 			source:   "(func local.get 0 local.get 1)",
diff --git a/tests/spectest/spec_test.go b/tests/spectest/spec_test.go
index ece5d5a9..689f0ef9 100644
--- a/tests/spectest/spec_test.go
+++ b/tests/spectest/spec_test.go
@@ -13,10 +13,13 @@ import (
 
 	"github.com/stretchr/testify/require"
 
+	"github.com/tetratelabs/wazero/api"
+	"github.com/tetratelabs/wazero/internal/leb128"
 	"github.com/tetratelabs/wazero/internal/wasm"
 	"github.com/tetratelabs/wazero/internal/wasm/binary"
 	"github.com/tetratelabs/wazero/internal/wasm/interpreter"
 	"github.com/tetratelabs/wazero/internal/wasm/jit"
+	"github.com/tetratelabs/wazero/internal/wasm/text"
 	"github.com/tetratelabs/wazero/internal/wasmruntime"
 )
 
@@ -195,80 +198,76 @@ func (c command) expectedError() (err error) {
 	return
 }
 
+// addSpectestModule adds a module that drops inputs and returns globals as 666 per the default test harness.
+//
+// See https://github.com/WebAssembly/spec/blob/wg-1.0/test/core/imports.wast
+// See https://github.com/WebAssembly/spec/blob/wg-1.0/interpreter/script/js.ml#L13-L25
 func addSpectestModule(t *testing.T, store *wasm.Store) {
-	memoryLimitMax := uint32(2)
+	mod, err := text.DecodeModule([]byte(`(module $spectest
+(; TODO
+  (global (export "global_i32") i32)
+  (global (export "global_f32") f32)
+  (global (export "global_f64") f64)
+
+  (table (export "table") 10 20 funcref)
+;)
+
+;; TODO: revisit inlining after #215
+
+  (memory 1 2)
+    (export "memory" (memory 0))
+
+;; Note: the following aren't host functions that print to console as it would clutter it. These only drop the inputs.
+  (func)
+     (export "print" (func 0))
+
+  (func (param i32) local.get 0 drop)
+     (export "print_i32" (func 1))
+
+  (func (param i64) local.get 0 drop)
+     (export "print_i64" (func 2))
+
+  (func (param f32) local.get 0 drop)
+     (export "print_f32" (func 3))
+
+  (func (param f64) local.get 0 drop)
+     (export "print_f64" (func 4))
+
+  (func (param i32 f32) local.get 0 drop local.get 1 drop)
+     (export "print_i32_f32" (func 5))
+
+  (func (param f64 f64) local.get 0 drop local.get 1 drop)
+     (export "print_f64_f64" (func 6))
+)`), wasm.Features20191205, wasm.MemoryMaxPages)
+	require.NoError(t, err)
+
+	// (global (export "global_i32") i32 (i32.const 666))
+	mod.GlobalSection = append(mod.GlobalSection, &wasm.Global{
+		Type: &wasm.GlobalType{ValType: wasm.ValueTypeI32},
+		Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeI32Const, Data: leb128.EncodeUint32(666)},
+	})
+	mod.ExportSection["global_i32"] = &wasm.Export{Name: "global_i32", Index: 0, Type: wasm.ExternTypeGlobal}
+
+	// (global (export "global_f32") f32 (f32.const 666))
+	mod.GlobalSection = append(mod.GlobalSection, &wasm.Global{
+		Type: &wasm.GlobalType{ValType: wasm.ValueTypeF32},
+		Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeF32Const, Data: leb128.EncodeUint64(api.EncodeF32(666))},
+	})
+	mod.ExportSection["global_f32"] = &wasm.Export{Name: "global_f32", Index: 1, Type: wasm.ExternTypeGlobal}
+
+	// (global (export "global_f64") f64 (f64.const 666))
+	mod.GlobalSection = append(mod.GlobalSection, &wasm.Global{
+		Type: &wasm.GlobalType{ValType: wasm.ValueTypeF64},
+		Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeF64Const, Data: leb128.EncodeUint64(api.EncodeF64(666))},
+	})
+	mod.ExportSection["global_f64"] = &wasm.Export{Name: "global_f64", Index: 2, Type: wasm.ExternTypeGlobal}
+
+	//  (table (export "table") 10 20 funcref)
 	tableLimitMax := uint32(20)
+	mod.TableSection = &wasm.Table{Min: 10, Max: &tableLimitMax}
+	mod.ExportSection["table"] = &wasm.Export{Name: "table", Index: 0, Type: wasm.ExternTypeTable}
 
-	mod := &wasm.Module{
-		FunctionSection: []uint32{
-			0, // print
-			1, // print_i32
-			2, // print_i64
-			3, // print_f32
-			4, // print_f64
-			5, // print_f64
-			6, // print_f64
-		},
-		TypeSection: []*wasm.FunctionType{
-			{},                                  // print
-			{Params: []byte{wasm.ValueTypeI32}}, // print_i32
-			{Params: []byte{wasm.ValueTypeI64}}, // print_i64
-			{Params: []byte{wasm.ValueTypeF32}}, // print_f32
-			{Params: []byte{wasm.ValueTypeF64}}, // print_f64
-			{Params: []byte{wasm.ValueTypeI32, wasm.ValueTypeF32}}, // print_i32_f32
-			{Params: []byte{wasm.ValueTypeF64, wasm.ValueTypeF64}}, // print_f64_f64
-		},
-		CodeSection: []*wasm.Code{
-			{Body: []byte{wasm.OpcodeEnd}},                                                                                   // print
-			{Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeDrop, wasm.OpcodeEnd}},                                          // print_i32
-			{Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeDrop, wasm.OpcodeEnd}},                                          // print_i64
-			{Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeDrop, wasm.OpcodeEnd}},                                          // print_f32
-			{Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeDrop, wasm.OpcodeEnd}},                                          // print_f64
-			{Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeDrop, wasm.OpcodeLocalGet, 1, wasm.OpcodeDrop, wasm.OpcodeEnd}}, // print_i32_f32
-			{Body: []byte{wasm.OpcodeLocalGet, 0, wasm.OpcodeDrop, wasm.OpcodeLocalGet, 1, wasm.OpcodeDrop, wasm.OpcodeEnd}}, // print_f64_f64
-		},
-		GlobalSection: []*wasm.Global{
-			{ // global_i32
-				Type: &wasm.GlobalType{ValType: wasm.ValueTypeI32},
-				Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeI32Const, Data: []byte{0x9a, 0x5} /* = 666 */},
-			},
-			{ // global_i64
-				Type: &wasm.GlobalType{ValType: wasm.ValueTypeI64},
-				Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeI64Const, Data: []byte{0x9a, 0x5} /* = 666 */},
-			},
-			{ // global_f32
-				Type: &wasm.GlobalType{ValType: wasm.ValueTypeF32},
-				Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeF32Const, Data: []byte{0x44, 0x26, 0x80, 0x00}},
-			},
-			{ // global_f64
-				Type: &wasm.GlobalType{ValType: wasm.ValueTypeF64},
-				Init: &wasm.ConstantExpression{Opcode: wasm.OpcodeF64Const, Data: []byte{0x40, 0x84, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00}},
-			},
-		},
-		MemorySection: &wasm.Memory{
-			Min: 1, Max: memoryLimitMax,
-		},
-		TableSection: &wasm.Table{
-			Min: 10, Max: &tableLimitMax,
-		},
-		ExportSection: map[string]*wasm.Export{
-			"print":         {Name: "print", Index: 0, Type: wasm.ExternTypeFunc},
-			"print_i32":     {Name: "print_i32", Index: 1, Type: wasm.ExternTypeFunc},
-			"print_i64":     {Name: "print_i64", Index: 2, Type: wasm.ExternTypeFunc},
-			"print_f32":     {Name: "print_f32", Index: 3, Type: wasm.ExternTypeFunc},
-			"print_f64":     {Name: "print_f64", Index: 4, Type: wasm.ExternTypeFunc},
-			"print_i32_f32": {Name: "print_i32_f32", Index: 5, Type: wasm.ExternTypeFunc},
-			"print_f64_f64": {Name: "print_f64_f64", Index: 6, Type: wasm.ExternTypeFunc},
-			"global_i32":    {Name: "global_i32", Index: 0, Type: wasm.ExternTypeGlobal},
-			"global_i64":    {Name: "global_i64", Index: 1, Type: wasm.ExternTypeGlobal},
-			"global_f32":    {Name: "global_f32", Index: 2, Type: wasm.ExternTypeGlobal},
-			"global_f64":    {Name: "global_f64", Index: 3, Type: wasm.ExternTypeGlobal},
-			"table":         {Name: "table", Index: 0, Type: wasm.ExternTypeTable},
-			"memory":        {Name: "memory", Index: 0, Type: wasm.ExternTypeMemory},
-		},
-	}
-	require.NoError(t, mod.Validate(wasm.Features20191205))
-	_, err := store.Instantiate(context.Background(), mod, "spectest", nil)
+	_, err = store.Instantiate(context.Background(), mod, mod.NameSection.ModuleName, wasm.DefaultSysContext())
 	require.NoError(t, err)
 }