diff options
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/wasm')
3 files changed, 78 insertions, 12 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go index 604489228..96d061a7b 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go @@ -4,6 +4,7 @@ import ( "bytes" "errors" "fmt" + "slices" "strconv" "strings" @@ -480,11 +481,9 @@ func (m *Module) validateFunctionWithMaxStackValues( // function type might result in invalid value types if the block is the outermost label // which equals the function's type. if lnLabel.op != OpcodeLoop { // Loop operation doesn't require results since the continuation is the beginning of the loop. - defaultLabelType = make([]ValueType, len(lnLabel.blockType.Results)) - copy(defaultLabelType, lnLabel.blockType.Results) + defaultLabelType = slices.Clone(lnLabel.blockType.Results) } else { - defaultLabelType = make([]ValueType, len(lnLabel.blockType.Params)) - copy(defaultLabelType, lnLabel.blockType.Params) + defaultLabelType = slices.Clone(lnLabel.blockType.Params) } if enabledFeatures.IsEnabled(api.CoreFeatureReferenceTypes) { @@ -534,7 +533,7 @@ func (m *Module) validateFunctionWithMaxStackValues( // br_table instruction is stack-polymorphic. valueTypeStack.unreachable() - } else if op == OpcodeCall { + } else if op == OpcodeCall || op == OpcodeTailCallReturnCall { pc++ index, num, err := leb128.LoadUint32(body[pc:]) if err != nil { @@ -544,16 +543,35 @@ func (m *Module) validateFunctionWithMaxStackValues( if int(index) >= len(functions) { return fmt.Errorf("invalid function index") } + + var opcodeName string + if op == OpcodeCall { + opcodeName = OpcodeCallName + } else { + opcodeName = OpcodeTailCallReturnCallName + } + funcType := &m.TypeSection[functions[index]] for i := 0; i < len(funcType.Params); i++ { if err := valueTypeStack.popAndVerifyType(funcType.Params[len(funcType.Params)-1-i]); err != nil { - return fmt.Errorf("type mismatch on %s operation param type: %v", OpcodeCallName, err) + return fmt.Errorf("type mismatch on %s operation param type: %v", opcodeName, err) } } for _, exp := range funcType.Results { valueTypeStack.push(exp) } - } else if op == OpcodeCallIndirect { + if op == OpcodeTailCallReturnCall { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTailCall); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeTailCallReturnCallName, err) + } + // Same formatting as OpcodeEnd on the outer-most block + if err := valueTypeStack.requireStackValues(false, "", functionType.Results, false); err != nil { + return err + } + // behaves as a jump. + valueTypeStack.unreachable() + } + } else if op == OpcodeCallIndirect || op == OpcodeTailCallReturnCallIndirect { pc++ typeIndex, num, err := leb128.LoadUint32(body[pc:]) if err != nil { @@ -561,8 +579,15 @@ func (m *Module) validateFunctionWithMaxStackValues( } pc += num + var opcodeName string + if op == OpcodeCallIndirect { + opcodeName = OpcodeCallIndirectName + } else { + opcodeName = OpcodeTailCallReturnCallIndirectName + } + if int(typeIndex) >= len(m.TypeSection) { - return fmt.Errorf("invalid type index at %s: %d", OpcodeCallIndirectName, typeIndex) + return fmt.Errorf("invalid type index at %s: %d", opcodeName, typeIndex) } tableIndex, num, err := leb128.LoadUint32(body[pc:]) @@ -582,21 +607,33 @@ func (m *Module) validateFunctionWithMaxStackValues( table := tables[tableIndex] if table.Type != RefTypeFuncref { - return fmt.Errorf("table is not funcref type but was %s for %s", RefTypeName(table.Type), OpcodeCallIndirectName) + return fmt.Errorf("table is not funcref type but was %s for %s", RefTypeName(table.Type), opcodeName) } if err = valueTypeStack.popAndVerifyType(ValueTypeI32); err != nil { - return fmt.Errorf("cannot pop the offset in table for %s", OpcodeCallIndirectName) + return fmt.Errorf("cannot pop the offset in table for %s", opcodeName) } funcType := &m.TypeSection[typeIndex] for i := 0; i < len(funcType.Params); i++ { if err = valueTypeStack.popAndVerifyType(funcType.Params[len(funcType.Params)-1-i]); err != nil { - return fmt.Errorf("type mismatch on %s operation input type", OpcodeCallIndirectName) + return fmt.Errorf("type mismatch on %s operation input type", opcodeName) } } for _, exp := range funcType.Results { valueTypeStack.push(exp) } + + if op == OpcodeTailCallReturnCallIndirect { + if err := enabledFeatures.RequireEnabled(experimental.CoreFeaturesTailCall); err != nil { + return fmt.Errorf("%s invalid as %v", OpcodeTailCallReturnCallIndirectName, err) + } + // Same formatting as OpcodeEnd on the outer-most block + if err := valueTypeStack.requireStackValues(false, "", functionType.Results, false); err != nil { + return err + } + // behaves as a jump. + valueTypeStack.unreachable() + } } else if OpcodeI32Eqz <= op && op <= OpcodeI64Extend32S { switch op { case OpcodeI32Eqz: diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go index 67f196b8b..7f76b1e52 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go @@ -777,6 +777,16 @@ const ( OpcodeAtomicI64Rmw32CmpxchgU OpcodeAtomic = 0x4e ) +// OpcodeTailCall represents an opcode of a tail call instructions. +// +// These opcodes are toggled with CoreFeaturesTailCall. +type OpcodeTailCall = byte + +const ( + OpcodeTailCallReturnCall OpcodeTailCall = 0x12 + OpcodeTailCallReturnCallIndirect OpcodeTailCall = 0x13 +) + const ( OpcodeUnreachableName = "unreachable" OpcodeNopName = "nop" @@ -1864,3 +1874,18 @@ var atomicInstructionName = map[OpcodeAtomic]string{ func AtomicInstructionName(oc OpcodeAtomic) (ret string) { return atomicInstructionName[oc] } + +const ( + OpcodeTailCallReturnCallName = "return_call" + OpcodeTailCallReturnCallIndirectName = "return_call_indirect" +) + +var tailCallInstructionName = map[OpcodeTailCall]string{ + OpcodeTailCallReturnCall: OpcodeTailCallReturnCallName, + OpcodeTailCallReturnCallIndirect: OpcodeTailCallReturnCallIndirectName, +} + +// TailCallInstructionName returns the instruction name corresponding to the tail call Opcode. +func TailCallInstructionName(oc OpcodeTailCall) (ret string) { + return tailCallInstructionName[oc] +} diff --git a/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go b/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go index 2123693c6..1df1764df 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go +++ b/vendor/github.com/tetratelabs/wazero/internal/wasm/table.go @@ -326,10 +326,14 @@ func (t *TableInstance) Grow(delta uint32, initialRef Reference) (currentLen uin newLen >= math.MaxUint32 || (t.Max != nil && newLen > int64(*t.Max)) { return 0xffffffff // = -1 in signed 32-bit integer. } + t.References = append(t.References, make([]uintptr, delta)...) + if initialRef == 0 { + return + } // Uses the copy trick for faster filling the new region with the initial value. - // https://gist.github.com/taylorza/df2f89d5f9ab3ffd06865062a4cf015d + // https://github.com/golang/go/blob/go1.24.0/src/slices/slices.go#L514-L517 newRegion := t.References[currentLen:] newRegion[0] = initialRef for i := 1; i < len(newRegion); i *= 2 { |
