summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/wasm')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/wasm/func_validation.go59
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/wasm/instruction.go25
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/wasm/table.go6
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 {