nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: tetratelabs/wazero
Pull request #682 (2022-07-12 07:25:08)

ir: correctly ignore unreachable br/br_if
This is the first bug found by wazero-fuzz repository:

```wat
(module
  (type (func))
  (func (type 0)
    br 0 ;; return the function, therefore the following instructions are unreachable.
    block
      br 1 ;; <------------ this is unreachable and must be ignored, not causing panic :D 
    end))
```


Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>


Patch:
diff --git a/internal/wazeroir/compiler.go b/internal/wazeroir/compiler.go
index 59b08350..19fca988 100644
--- a/internal/wazeroir/compiler.go
+++ b/internal/wazeroir/compiler.go
@@ -587,6 +587,11 @@ operatorSwitch:
 		}
 		c.pc += n
 
+		if c.unreachableState.on {
+			// If it is currently in unreachable, br is no-op.
+			break operatorSwitch
+		}
+
 		targetFrame := c.controlFrames.get(int(targetIndex))
 		targetFrame.ensureContinuation()
 		dropOp := &OperationDrop{Depth: c.getFrameDropRange(targetFrame, false)}
@@ -607,6 +612,11 @@ operatorSwitch:
 		}
 		c.pc += n
 
+		if c.unreachableState.on {
+			// If it is currently in unreachable, br-if is no-op.
+			break operatorSwitch
+		}
+
 		targetFrame := c.controlFrames.get(int(targetIndex))
 		targetFrame.ensureContinuation()
 		drop := c.getFrameDropRange(targetFrame, false)


Test patch:
diff --git a/internal/wazeroir/compiler_test.go b/internal/wazeroir/compiler_test.go
index e81f5598..605d10e2 100644
--- a/internal/wazeroir/compiler_test.go
+++ b/internal/wazeroir/compiler_test.go
@@ -2457,3 +2457,53 @@ func TestCompile_Vec(t *testing.T) {
 		})
 	}
 }
+
+// TestCompile_unreachable_br_brif ensures that unreachable br and br_if instructions are correctly ignored.
+func TestCompile_unreachable_br_brif(t *testing.T) {
+	tests := []struct {
+		name     string
+		mod      *wasm.Module
+		expected []Operation
+	}{
+		{
+			name: "br",
+			mod: &wasm.Module{
+				TypeSection:     []*wasm.FunctionType{{}},
+				FunctionSection: []wasm.Index{0},
+				CodeSection: []*wasm.Code{{Body: []byte{
+					wasm.OpcodeBr, 0, // Return the function -> the followings are unreachable.
+					wasm.OpcodeBlock, 0,
+					wasm.OpcodeBr, 1,
+					wasm.OpcodeEnd, // End the block.
+					wasm.OpcodeEnd, // End the function.
+				}}},
+			},
+			expected: []Operation{&OperationBr{Target: &BranchTarget{}}},
+		},
+		{
+			name: "br_if",
+			mod: &wasm.Module{
+				TypeSection:     []*wasm.FunctionType{{}},
+				FunctionSection: []wasm.Index{0},
+				CodeSection: []*wasm.Code{{Body: []byte{
+					wasm.OpcodeBr, 0, // Return the function -> the followings are unreachable.
+					wasm.OpcodeBlock, 0,
+					wasm.OpcodeI32Const, 1,
+					wasm.OpcodeBrIf, 1,
+					wasm.OpcodeEnd, // End the block.
+					wasm.OpcodeEnd, // End the function.
+				}}},
+			},
+			expected: []Operation{&OperationBr{Target: &BranchTarget{}}},
+		},
+	}
+
+	for _, tt := range tests {
+		tc := tt
+		t.Run(tc.name, func(t *testing.T) {
+			res, err := CompileFunctions(ctx, wasm.Features20220419, tc.mod)
+			require.NoError(t, err)
+			require.Equal(t, tc.expected, res[0].Operations)
+		})
+	}
+}
Repository: tetratelabs/wazero
Pull request #687 (2022-07-13 00:34:58)

Allow externref in table validation
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>


Patch:
diff --git a/internal/wasm/table.go b/internal/wasm/table.go
index 727f6897..c14f947c 100644
--- a/internal/wasm/table.go
+++ b/internal/wasm/table.go
@@ -177,8 +177,8 @@ func (m *Module) validateTable(enabledFeatures Features, tables []*Table, maximu
 				return nil, fmt.Errorf("unknown table %d as active element target", elem.TableIndex)
 			}
 
-			if elem.Type != RefTypeFuncref {
-				return nil, fmt.Errorf("only funcref element can be used to initialize table, but was %s", RefTypeName(elem.Type))
+			if elem.Type != RefTypeFuncref && elem.Type != RefTypeExternref {
+				return nil, fmt.Errorf("only funcref or externref element can be used to initialize table, but was %s", RefTypeName(elem.Type))
 			}
 
 			// global.get needs to be discovered during initialization


Test patch:
diff --git a/internal/wasm/table_test.go b/internal/wasm/table_test.go
index 59f46f0e..6404f037 100644
--- a/internal/wasm/table_test.go
+++ b/internal/wasm/table_test.go
@@ -349,7 +349,7 @@ func TestModule_validateTable_Errors(t *testing.T) {
 			expectedErr: "too many tables in a module: 6 given with limit 5",
 		},
 		{
-			name: "non funcref",
+			name: "unknown ref type",
 			input: &Module{
 				TableSection: []*Table{{}},
 				ElementSection: []*ElementSegment{
@@ -358,11 +358,11 @@ func TestModule_validateTable_Errors(t *testing.T) {
 							Opcode: OpcodeI32Const,
 							Data:   leb128.EncodeUint64(math.MaxUint64),
 						},
-						Type: RefTypeExternref,
+						Type: 0xff,
 					},
 				},
 			},
-			expectedErr: "only funcref element can be used to initialize table, but was externref",
+			expectedErr: "only funcref or externref element can be used to initialize table, but was unknown(0xff)",
 		},
 		{
 			name: "constant derived element offset - decode error",
Repository: tetratelabs/wazero
Pull request #689 (2022-07-13 02:41:46)

ir: correctly ignores unreachable br_table instructions
Found via wazero-fuzz, though in practice this will unlikely happen:

```wat
(module
  (type (;0;) (func (param i32)))
  (func (;0;) (type 0) (param i32)
    local.get 0
    local.tee 0
    local.tee 0
    br_table 0 (;@0;) 0 (;@0;)
    block (result i32)  ;; label = @1
      local.get 0
      br_table 1 (;@0;) 1 (;@0;)
      i32.const 0
    end
    drop)
  (export "r" (func 0)))
```

Similar to #682 

Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>


Patch:
diff --git a/internal/wazeroir/compiler.go b/internal/wazeroir/compiler.go
index 6c3a89e4..cb4efa63 100644
--- a/internal/wazeroir/compiler.go
+++ b/internal/wazeroir/compiler.go
@@ -655,6 +655,11 @@ operatorSwitch:
 		}
 		c.pc += n
 
+		if c.unreachableState.on {
+			// If it is currently in unreachable, br_table is no-op.
+			break operatorSwitch
+		}
+
 		// Read the branch targets.
 		targets := make([]*BranchTargetDrop, numTargets)
 		for i := range targets {


Test patch:
diff --git a/internal/wazeroir/compiler_test.go b/internal/wazeroir/compiler_test.go
index fa9a5152..a46bc34c 100644
--- a/internal/wazeroir/compiler_test.go
+++ b/internal/wazeroir/compiler_test.go
@@ -2458,8 +2458,8 @@ func TestCompile_Vec(t *testing.T) {
 	}
 }
 
-// TestCompile_unreachable_br_brif ensures that unreachable br and br_if instructions are correctly ignored.
-func TestCompile_unreachable_br_brif(t *testing.T) {
+// TestCompile_unreachable_Br_BrIf_BrTable ensures that unreachable br/br_if/br_table instructions are correctly ignored.
+func TestCompile_unreachable_Br_BrIf_BrTable(t *testing.T) {
 	tests := []struct {
 		name     string
 		mod      *wasm.Module
@@ -2496,6 +2496,21 @@ func TestCompile_unreachable_br_brif(t *testing.T) {
 			},
 			expected: []Operation{&OperationBr{Target: &BranchTarget{}}},
 		},
+		{
+			name: "br_table",
+			mod: &wasm.Module{
+				TypeSection:     []*wasm.FunctionType{{}},
+				FunctionSection: []wasm.Index{0},
+				CodeSection: []*wasm.Code{{Body: []byte{
+					wasm.OpcodeBr, 0, // Return the function -> the followings are unreachable.
+					wasm.OpcodeBlock, 0,
+					wasm.OpcodeBrTable, 1, 1, 1,
+					wasm.OpcodeEnd, // End the block.
+					wasm.OpcodeEnd, // End the function.
+				}}},
+			},
+			expected: []Operation{&OperationBr{Target: &BranchTarget{}}},
+		},
 	}
 
 	for _, tt := range tests {
Repository: tetratelabs/wazero
Pull request #690 (2022-07-13 05:44:59)

ir: correctly ignores unreachable br_table instructions (part2)
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>

mathetake: part 2 of #689 

Patch:
diff --git a/internal/wazeroir/compiler.go b/internal/wazeroir/compiler.go
index cb4efa63..0baf9bb2 100644
--- a/internal/wazeroir/compiler.go
+++ b/internal/wazeroir/compiler.go
@@ -657,6 +657,15 @@ operatorSwitch:
 
 		if c.unreachableState.on {
 			// If it is currently in unreachable, br_table is no-op.
+			// But before proceeding to the next instruction, we must advance the pc
+			// according to the number of br_table targets.
+			for i := uint32(0); i <= numTargets; i++ { // inclusive as we also need to read the index of default target.
+				_, n, err := leb128.DecodeUint32(r)
+				if err != nil {
+					return fmt.Errorf("error reading target %d in br_table: %w", i, err)
+				}
+				c.pc += n
+			}
 			break operatorSwitch
 		}
 


Test patch:
diff --git a/internal/wazeroir/compiler_test.go b/internal/wazeroir/compiler_test.go
index a46bc34c..3fda7c57 100644
--- a/internal/wazeroir/compiler_test.go
+++ b/internal/wazeroir/compiler_test.go
@@ -2504,7 +2504,7 @@ func TestCompile_unreachable_Br_BrIf_BrTable(t *testing.T) {
 				CodeSection: []*wasm.Code{{Body: []byte{
 					wasm.OpcodeBr, 0, // Return the function -> the followings are unreachable.
 					wasm.OpcodeBlock, 0,
-					wasm.OpcodeBrTable, 1, 1, 1,
+					wasm.OpcodeBrTable, 2, 2, 3,
 					wasm.OpcodeEnd, // End the block.
 					wasm.OpcodeEnd, // End the function.
 				}}},