diff options
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/engine/interpreter')
-rw-r--r-- | vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go | 78 | ||||
-rw-r--r-- | vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go | 26 |
2 files changed, 56 insertions, 48 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go index 56dfac620..4e20e4b2c 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/compiler.go @@ -26,11 +26,14 @@ const ( type ( controlFrame struct { frameID uint32 - // originalStackLen holds the number of values on the stack + // originalStackLenWithoutParam holds the number of values on the stack // when Start executing this control frame minus params for the block. originalStackLenWithoutParam int - blockType *wasm.FunctionType - kind controlFrameKind + // originalStackLenWithoutParamUint64 is almost the same as originalStackLenWithoutParam + // except that it holds the number of values on the stack in uint64. + originalStackLenWithoutParamUint64 int + blockType *wasm.FunctionType + kind controlFrameKind } controlFrames struct{ frames []controlFrame } ) @@ -157,9 +160,11 @@ type compiler struct { enabledFeatures api.CoreFeatures callFrameStackSizeInUint64 int stack []unsignedType - currentFrameID uint32 - controlFrames controlFrames - unreachableState struct { + // stackLenInUint64 is the length of the stack in uint64. + stackLenInUint64 int + currentFrameID uint32 + controlFrames controlFrames + unreachableState struct { on bool depth int } @@ -341,6 +346,7 @@ func (c *compiler) Next() (*compilationResult, error) { c.pc = 0 c.currentOpPC = 0 c.currentFrameID = 0 + c.stackLenInUint64 = 0 c.unreachableState.on, c.unreachableState.depth = false, 0 if err := c.compile(sig, code.Body, code.LocalTypes, code.BodyOffsetInCodeSection); err != nil { @@ -449,10 +455,11 @@ operatorSwitch: // Create a new frame -- entering this block. frame := controlFrame{ - frameID: c.nextFrameID(), - originalStackLenWithoutParam: len(c.stack) - len(bt.Params), - kind: controlFrameKindBlockWithoutContinuationLabel, - blockType: bt, + frameID: c.nextFrameID(), + originalStackLenWithoutParam: len(c.stack) - len(bt.Params), + originalStackLenWithoutParamUint64: c.stackLenInUint64 - bt.ParamNumInUint64, + kind: controlFrameKindBlockWithoutContinuationLabel, + blockType: bt, } c.controlFrames.push(frame) @@ -473,10 +480,11 @@ operatorSwitch: // Create a new frame -- entering loop. frame := controlFrame{ - frameID: c.nextFrameID(), - originalStackLenWithoutParam: len(c.stack) - len(bt.Params), - kind: controlFrameKindLoop, - blockType: bt, + frameID: c.nextFrameID(), + originalStackLenWithoutParam: len(c.stack) - len(bt.Params), + originalStackLenWithoutParamUint64: c.stackLenInUint64 - bt.ParamNumInUint64, + kind: controlFrameKindLoop, + blockType: bt, } c.controlFrames.push(frame) @@ -515,8 +523,9 @@ operatorSwitch: // Create a new frame -- entering if. frame := controlFrame{ - frameID: c.nextFrameID(), - originalStackLenWithoutParam: len(c.stack) - len(bt.Params), + frameID: c.nextFrameID(), + originalStackLenWithoutParam: len(c.stack) - len(bt.Params), + originalStackLenWithoutParamUint64: c.stackLenInUint64 - bt.ParamNumInUint64, // Note this will be set to controlFrameKindIfWithElse // when else opcode found later. kind: controlFrameKindIfWithoutElse, @@ -543,7 +552,7 @@ operatorSwitch: // If it is currently in unreachable, and the non-nested if, // reset the stack so we can correctly handle the else block. top := c.controlFrames.top() - c.stack = c.stack[:top.originalStackLenWithoutParam] + c.stackSwitchAt(top) top.kind = controlFrameKindIfWithElse // Re-push the parameters to the if block so that else block can use them. @@ -572,7 +581,7 @@ operatorSwitch: // Reset the stack manipulated by the then block, and re-push the block param types to the stack. - c.stack = c.stack[:frame.originalStackLenWithoutParam] + c.stackSwitchAt(frame) for _, t := range frame.blockType.Params { c.stackPush(wasmValueTypeTounsignedType(t)) } @@ -601,7 +610,7 @@ operatorSwitch: return nil } - c.stack = c.stack[:frame.originalStackLenWithoutParam] + c.stackSwitchAt(frame) for _, t := range frame.blockType.Results { c.stackPush(wasmValueTypeTounsignedType(t)) } @@ -628,7 +637,7 @@ operatorSwitch: // We need to reset the stack so that // the values pushed inside the block. dropOp := newOperationDrop(c.getFrameDropRange(frame, true)) - c.stack = c.stack[:frame.originalStackLenWithoutParam] + c.stackSwitchAt(frame) // Push the result types onto the stack. for _, t := range frame.blockType.Results { @@ -3505,6 +3514,11 @@ func (c *compiler) stackPeek() (ret unsignedType) { return } +func (c *compiler) stackSwitchAt(frame *controlFrame) { + c.stack = c.stack[:frame.originalStackLenWithoutParam] + c.stackLenInUint64 = frame.originalStackLenWithoutParamUint64 +} + func (c *compiler) stackPop() (ret unsignedType) { // No need to check stack bound // as we can assume that all the operations @@ -3512,11 +3526,13 @@ func (c *compiler) stackPop() (ret unsignedType) { // at module validation phase. ret = c.stack[len(c.stack)-1] c.stack = c.stack[:len(c.stack)-1] + c.stackLenInUint64 -= 1 + int(unsignedTypeV128&ret>>2) return } func (c *compiler) stackPush(ts unsignedType) { c.stack = append(c.stack, ts) + c.stackLenInUint64 += 1 + int(unsignedTypeV128&ts>>2) } // emit adds the operations into the result. @@ -3565,7 +3581,7 @@ func (c *compiler) emitDefaultValue(t wasm.ValueType) { // of the n-th local. func (c *compiler) localDepth(index wasm.Index) int { height := c.localIndexToStackHeightInUint64[index] - return c.stackLenInUint64(len(c.stack)) - 1 - int(height) + return c.stackLenInUint64 - 1 - height } func (c *compiler) localType(index wasm.Index) (t wasm.ValueType) { @@ -3592,14 +3608,7 @@ func (c *compiler) getFrameDropRange(frame *controlFrame, isEnd bool) inclusiveR } else { start = frame.blockType.ResultNumInUint64 } - var end int - if frame.kind == controlFrameKindFunction { - // On the function return, we eliminate all the contents on the stack - // including locals (existing below of frame.originalStackLen) - end = c.stackLenInUint64(len(c.stack)) - 1 - } else { - end = c.stackLenInUint64(len(c.stack)) - 1 - c.stackLenInUint64(frame.originalStackLenWithoutParam) - } + end := c.stackLenInUint64 - 1 - frame.originalStackLenWithoutParamUint64 if start <= end { return inclusiveRange{Start: int32(start), End: int32(end)} } else { @@ -3607,17 +3616,6 @@ func (c *compiler) getFrameDropRange(frame *controlFrame, isEnd bool) inclusiveR } } -func (c *compiler) stackLenInUint64(ceil int) (ret int) { - for i := 0; i < ceil; i++ { - if c.stack[i] == unsignedTypeV128 { - ret += 2 - } else { - ret++ - } - } - return -} - func (c *compiler) readMemoryArg(tag string) (memoryArg, error) { c.result.UsesMemory = true alignment, num, err := leb128.LoadUint32(c.body[c.pc+1:]) diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go index 18c5f4252..ee0b453ca 100644 --- a/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go +++ b/vendor/github.com/tetratelabs/wazero/internal/engine/interpreter/interpreter.go @@ -3901,14 +3901,9 @@ func (ce *callEngine) callNativeFunc(ctx context.Context, m *wasm.ModuleInstance case operationKindV128Dot: x2Hi, x2Lo := ce.popValue(), ce.popValue() x1Hi, x1Lo := ce.popValue(), ce.popValue() - ce.pushValue( - uint64(uint32(int32(int16(x1Lo>>0))*int32(int16(x2Lo>>0))+int32(int16(x1Lo>>16))*int32(int16(x2Lo>>16)))) | - (uint64(uint32(int32(int16(x1Lo>>32))*int32(int16(x2Lo>>32))+int32(int16(x1Lo>>48))*int32(int16(x2Lo>>48)))) << 32), - ) - ce.pushValue( - uint64(uint32(int32(int16(x1Hi>>0))*int32(int16(x2Hi>>0))+int32(int16(x1Hi>>16))*int32(int16(x2Hi>>16)))) | - (uint64(uint32(int32(int16(x1Hi>>32))*int32(int16(x2Hi>>32))+int32(int16(x1Hi>>48))*int32(int16(x2Hi>>48)))) << 32), - ) + lo, hi := v128Dot(x1Hi, x1Lo, x2Hi, x2Lo) + ce.pushValue(lo) + ce.pushValue(hi) frame.pc++ case operationKindV128ITruncSatFromF: hi, lo := ce.popValue(), ce.popValue() @@ -4584,3 +4579,18 @@ func (ce *callEngine) callGoFuncWithStack(ctx context.Context, m *wasm.ModuleIns ce.stack = ce.stack[0 : len(ce.stack)-shrinkLen] } } + +// v128Dot performs a dot product of two 64-bit vectors. +// Note: for some reason (which I suspect is due to a bug in Go compiler's regalloc), +// inlining this function causes a bug which happens **only when** we run with -race AND arm64 AND Go 1.22. +func v128Dot(x1Hi, x1Lo, x2Hi, x2Lo uint64) (uint64, uint64) { + r1 := int32(int16(x1Lo>>0)) * int32(int16(x2Lo>>0)) + r2 := int32(int16(x1Lo>>16)) * int32(int16(x2Lo>>16)) + r3 := int32(int16(x1Lo>>32)) * int32(int16(x2Lo>>32)) + r4 := int32(int16(x1Lo>>48)) * int32(int16(x2Lo>>48)) + r5 := int32(int16(x1Hi>>0)) * int32(int16(x2Hi>>0)) + r6 := int32(int16(x1Hi>>16)) * int32(int16(x2Hi>>16)) + r7 := int32(int16(x1Hi>>32)) * int32(int16(x2Hi>>32)) + r8 := int32(int16(x1Hi>>48)) * int32(int16(x2Hi>>48)) + return uint64(uint32(r1+r2)) | (uint64(uint32(r3+r4)) << 32), uint64(uint32(r5+r6)) | (uint64(uint32(r7+r8)) << 32) +} |