github.com/tetratelabs/wazero@v1.7.3-0.20240513003603-48f702e154b5/internal/engine/interpreter/compiler.go (about)

     1  package interpreter
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"fmt"
     7  	"math"
     8  	"strings"
     9  
    10  	"github.com/tetratelabs/wazero/api"
    11  	"github.com/tetratelabs/wazero/internal/leb128"
    12  	"github.com/tetratelabs/wazero/internal/wasm"
    13  )
    14  
    15  type controlFrameKind byte
    16  
    17  const (
    18  	controlFrameKindBlockWithContinuationLabel controlFrameKind = iota
    19  	controlFrameKindBlockWithoutContinuationLabel
    20  	controlFrameKindFunction
    21  	controlFrameKindLoop
    22  	controlFrameKindIfWithElse
    23  	controlFrameKindIfWithoutElse
    24  )
    25  
    26  type (
    27  	controlFrame struct {
    28  		frameID uint32
    29  		// originalStackLen holds the number of values on the stack
    30  		// when Start executing this control frame minus params for the block.
    31  		originalStackLenWithoutParam int
    32  		blockType                    *wasm.FunctionType
    33  		kind                         controlFrameKind
    34  	}
    35  	controlFrames struct{ frames []controlFrame }
    36  )
    37  
    38  func (c *controlFrame) ensureContinuation() {
    39  	// Make sure that if the frame is block and doesn't have continuation,
    40  	// change the Kind so we can emit the continuation block
    41  	// later when we reach the End instruction of this frame.
    42  	if c.kind == controlFrameKindBlockWithoutContinuationLabel {
    43  		c.kind = controlFrameKindBlockWithContinuationLabel
    44  	}
    45  }
    46  
    47  func (c *controlFrame) asLabel() label {
    48  	switch c.kind {
    49  	case controlFrameKindBlockWithContinuationLabel,
    50  		controlFrameKindBlockWithoutContinuationLabel:
    51  		return newLabel(labelKindContinuation, c.frameID)
    52  	case controlFrameKindLoop:
    53  		return newLabel(labelKindHeader, c.frameID)
    54  	case controlFrameKindFunction:
    55  		return newLabel(labelKindReturn, 0)
    56  	case controlFrameKindIfWithElse,
    57  		controlFrameKindIfWithoutElse:
    58  		return newLabel(labelKindContinuation, c.frameID)
    59  	}
    60  	panic(fmt.Sprintf("unreachable: a bug in interpreterir implementation: %v", c.kind))
    61  }
    62  
    63  func (c *controlFrames) functionFrame() *controlFrame {
    64  	// No need to check stack bound
    65  	// as we can assume that all the operations
    66  	// are valid thanks to validateFunction
    67  	// at module validation phase.
    68  	return &c.frames[0]
    69  }
    70  
    71  func (c *controlFrames) get(n int) *controlFrame {
    72  	// No need to check stack bound
    73  	// as we can assume that all the operations
    74  	// are valid thanks to validateFunction
    75  	// at module validation phase.
    76  	return &c.frames[len(c.frames)-n-1]
    77  }
    78  
    79  func (c *controlFrames) top() *controlFrame {
    80  	// No need to check stack bound
    81  	// as we can assume that all the operations
    82  	// are valid thanks to validateFunction
    83  	// at module validation phase.
    84  	return &c.frames[len(c.frames)-1]
    85  }
    86  
    87  func (c *controlFrames) empty() bool {
    88  	return len(c.frames) == 0
    89  }
    90  
    91  func (c *controlFrames) pop() (frame *controlFrame) {
    92  	// No need to check stack bound
    93  	// as we can assume that all the operations
    94  	// are valid thanks to validateFunction
    95  	// at module validation phase.
    96  	frame = c.top()
    97  	c.frames = c.frames[:len(c.frames)-1]
    98  	return
    99  }
   100  
   101  func (c *controlFrames) push(frame controlFrame) {
   102  	c.frames = append(c.frames, frame)
   103  }
   104  
   105  func (c *compiler) initializeStack() {
   106  	// Reuse the existing slice.
   107  	c.localIndexToStackHeightInUint64 = c.localIndexToStackHeightInUint64[:0]
   108  	var current int
   109  	for _, lt := range c.sig.Params {
   110  		c.localIndexToStackHeightInUint64 = append(c.localIndexToStackHeightInUint64, current)
   111  		if lt == wasm.ValueTypeV128 {
   112  			current++
   113  		}
   114  		current++
   115  	}
   116  
   117  	if c.callFrameStackSizeInUint64 > 0 {
   118  		// We reserve the stack slots for result values below the return call frame slots.
   119  		if diff := c.sig.ResultNumInUint64 - c.sig.ParamNumInUint64; diff > 0 {
   120  			current += diff
   121  		}
   122  	}
   123  
   124  	// Non-func param locals Start after the return call frame.
   125  	current += c.callFrameStackSizeInUint64
   126  
   127  	for _, lt := range c.localTypes {
   128  		c.localIndexToStackHeightInUint64 = append(c.localIndexToStackHeightInUint64, current)
   129  		if lt == wasm.ValueTypeV128 {
   130  			current++
   131  		}
   132  		current++
   133  	}
   134  
   135  	// Push function arguments.
   136  	for _, t := range c.sig.Params {
   137  		c.stackPush(wasmValueTypeTounsignedType(t))
   138  	}
   139  
   140  	if c.callFrameStackSizeInUint64 > 0 {
   141  		// Reserve the stack slots for results.
   142  		for i := 0; i < c.sig.ResultNumInUint64-c.sig.ParamNumInUint64; i++ {
   143  			c.stackPush(unsignedTypeI64)
   144  		}
   145  
   146  		// Reserve the stack slots for call frame.
   147  		for i := 0; i < c.callFrameStackSizeInUint64; i++ {
   148  			c.stackPush(unsignedTypeI64)
   149  		}
   150  	}
   151  }
   152  
   153  // compiler is in charge of lowering raw Wasm function body to get compilationResult.
   154  // This is created per *wasm.Module and reused for all functions in it to reduce memory allocations.
   155  type compiler struct {
   156  	module                     *wasm.Module
   157  	enabledFeatures            api.CoreFeatures
   158  	callFrameStackSizeInUint64 int
   159  	stack                      []unsignedType
   160  	currentFrameID             uint32
   161  	controlFrames              controlFrames
   162  	unreachableState           struct {
   163  		on    bool
   164  		depth int
   165  	}
   166  	pc, currentOpPC uint64
   167  	result          compilationResult
   168  
   169  	// body holds the code for the function's body where Wasm instructions are stored.
   170  	body []byte
   171  	// sig is the function type of the target function.
   172  	sig *wasm.FunctionType
   173  	// localTypes holds the target function locals' value types except function params.
   174  	localTypes []wasm.ValueType
   175  	// localIndexToStackHeightInUint64 maps the local index (starting with function params) to the stack height
   176  	// where the local is places. This is the necessary mapping for functions who contain vector type locals.
   177  	localIndexToStackHeightInUint64 []int
   178  
   179  	// types hold all the function types in the module where the targe function exists.
   180  	types []wasm.FunctionType
   181  	// funcs holds the type indexes for all declared functions in the module where the target function exists.
   182  	funcs []uint32
   183  	// globals holds the global types for all declared globals in the module where the target function exists.
   184  	globals []wasm.GlobalType
   185  
   186  	// needSourceOffset is true if this module requires DWARF based stack trace.
   187  	needSourceOffset bool
   188  	// bodyOffsetInCodeSection is the offset of the body of this function in the original Wasm binary's code section.
   189  	bodyOffsetInCodeSection uint64
   190  
   191  	ensureTermination bool
   192  	// Pre-allocated bytes.Reader to be used in various places.
   193  	br             *bytes.Reader
   194  	funcTypeToSigs funcTypeToIRSignatures
   195  
   196  	next int
   197  }
   198  
   199  //lint:ignore U1000 for debugging only.
   200  func (c *compiler) stackDump() string {
   201  	strs := make([]string, 0, len(c.stack))
   202  	for _, s := range c.stack {
   203  		strs = append(strs, s.String())
   204  	}
   205  	return "[" + strings.Join(strs, ", ") + "]"
   206  }
   207  
   208  func (c *compiler) markUnreachable() {
   209  	c.unreachableState.on = true
   210  }
   211  
   212  func (c *compiler) resetUnreachable() {
   213  	c.unreachableState.on = false
   214  }
   215  
   216  // memoryType is the type of memory in a compiled module.
   217  type memoryType byte
   218  
   219  const (
   220  	// memoryTypeNone indicates there is no memory.
   221  	memoryTypeNone memoryType = iota
   222  	// memoryTypeStandard indicates there is a non-shared memory.
   223  	memoryTypeStandard
   224  	// memoryTypeShared indicates there is a shared memory.
   225  	memoryTypeShared
   226  )
   227  
   228  type compilationResult struct {
   229  	// Operations holds interpreterir operations compiled from Wasm instructions in a Wasm function.
   230  	Operations []unionOperation
   231  
   232  	// IROperationSourceOffsetsInWasmBinary is index-correlated with Operation and maps each operation to the corresponding source instruction's
   233  	// offset in the original WebAssembly binary.
   234  	// Non nil only when the given Wasm module has the DWARF section.
   235  	IROperationSourceOffsetsInWasmBinary []uint64
   236  
   237  	// LabelCallers maps label to the number of callers to that label.
   238  	// Here "callers" means that the call-sites which jumps to the label with br, br_if or br_table
   239  	// instructions.
   240  	//
   241  	// Note: zero possible and allowed in wasm. e.g.
   242  	//
   243  	//	(block
   244  	//	  (br 0)
   245  	//	  (block i32.const 1111)
   246  	//	)
   247  	//
   248  	// This example the label corresponding to `(block i32.const 1111)` is never be reached at runtime because `br 0` exits the function before we reach there
   249  	LabelCallers map[label]uint32
   250  	// UsesMemory is true if this function might use memory.
   251  	UsesMemory bool
   252  
   253  	// The following fields are per-module values, not per-function.
   254  
   255  	// Globals holds all the declarations of globals in the module from which this function is compiled.
   256  	Globals []wasm.GlobalType
   257  	// Functions holds all the declarations of function in the module from which this function is compiled, including itself.
   258  	Functions []wasm.Index
   259  	// Types holds all the types in the module from which this function is compiled.
   260  	Types []wasm.FunctionType
   261  	// Memory indicates the type of memory of the module.
   262  	Memory memoryType
   263  	// HasTable is true if the module from which this function is compiled has table declaration.
   264  	HasTable bool
   265  	// HasDataInstances is true if the module has data instances which might be used by memory.init or data.drop instructions.
   266  	HasDataInstances bool
   267  	// HasDataInstances is true if the module has element instances which might be used by table.init or elem.drop instructions.
   268  	HasElementInstances bool
   269  }
   270  
   271  // newCompiler returns the new *compiler for the given parameters.
   272  // Use compiler.Next function to get compilation result per function.
   273  func newCompiler(enabledFeatures api.CoreFeatures, callFrameStackSizeInUint64 int, module *wasm.Module, ensureTermination bool) (*compiler, error) {
   274  	functions, globals, mem, tables, err := module.AllDeclarations()
   275  	if err != nil {
   276  		return nil, err
   277  	}
   278  
   279  	hasTable, hasDataInstances, hasElementInstances := len(tables) > 0,
   280  		len(module.DataSection) > 0, len(module.ElementSection) > 0
   281  
   282  	var mt memoryType
   283  	switch {
   284  	case mem == nil:
   285  		mt = memoryTypeNone
   286  	case mem.IsShared:
   287  		mt = memoryTypeShared
   288  	default:
   289  		mt = memoryTypeStandard
   290  	}
   291  
   292  	types := module.TypeSection
   293  
   294  	c := &compiler{
   295  		module:                     module,
   296  		enabledFeatures:            enabledFeatures,
   297  		controlFrames:              controlFrames{},
   298  		callFrameStackSizeInUint64: callFrameStackSizeInUint64,
   299  		result: compilationResult{
   300  			Globals:             globals,
   301  			Functions:           functions,
   302  			Types:               types,
   303  			Memory:              mt,
   304  			HasTable:            hasTable,
   305  			HasDataInstances:    hasDataInstances,
   306  			HasElementInstances: hasElementInstances,
   307  			LabelCallers:        map[label]uint32{},
   308  		},
   309  		globals:           globals,
   310  		funcs:             functions,
   311  		types:             types,
   312  		ensureTermination: ensureTermination,
   313  		br:                bytes.NewReader(nil),
   314  		funcTypeToSigs: funcTypeToIRSignatures{
   315  			indirectCalls: make([]*signature, len(types)),
   316  			directCalls:   make([]*signature, len(types)),
   317  			wasmTypes:     types,
   318  		},
   319  		needSourceOffset: module.DWARFLines != nil,
   320  	}
   321  	return c, nil
   322  }
   323  
   324  // Next returns the next compilationResult for this compiler.
   325  func (c *compiler) Next() (*compilationResult, error) {
   326  	funcIndex := c.next
   327  	code := &c.module.CodeSection[funcIndex]
   328  	sig := &c.types[c.module.FunctionSection[funcIndex]]
   329  
   330  	// Reset the previous result.
   331  	c.result.Operations = c.result.Operations[:0]
   332  	c.result.IROperationSourceOffsetsInWasmBinary = c.result.IROperationSourceOffsetsInWasmBinary[:0]
   333  	c.result.UsesMemory = false
   334  	// Clears the existing entries in LabelCallers.
   335  	for frameID := uint32(0); frameID <= c.currentFrameID; frameID++ {
   336  		for k := labelKind(0); k < labelKindNum; k++ {
   337  			delete(c.result.LabelCallers, newLabel(k, frameID))
   338  		}
   339  	}
   340  	// Reset the previous states.
   341  	c.pc = 0
   342  	c.currentOpPC = 0
   343  	c.currentFrameID = 0
   344  	c.unreachableState.on, c.unreachableState.depth = false, 0
   345  
   346  	if err := c.compile(sig, code.Body, code.LocalTypes, code.BodyOffsetInCodeSection); err != nil {
   347  		return nil, err
   348  	}
   349  	c.next++
   350  	return &c.result, nil
   351  }
   352  
   353  // Compile lowers given function instance into interpreterir operations
   354  // so that the resulting operations can be consumed by the interpreter
   355  // or the compiler compilation engine.
   356  func (c *compiler) compile(sig *wasm.FunctionType, body []byte, localTypes []wasm.ValueType, bodyOffsetInCodeSection uint64) error {
   357  	// Set function specific fields.
   358  	c.body = body
   359  	c.localTypes = localTypes
   360  	c.sig = sig
   361  	c.bodyOffsetInCodeSection = bodyOffsetInCodeSection
   362  
   363  	// Reuses the underlying slices.
   364  	c.stack = c.stack[:0]
   365  	c.controlFrames.frames = c.controlFrames.frames[:0]
   366  
   367  	c.initializeStack()
   368  
   369  	// Emit const expressions for locals.
   370  	// Note that here we don't take function arguments
   371  	// into account, meaning that callers must push
   372  	// arguments before entering into the function body.
   373  	for _, t := range c.localTypes {
   374  		c.emitDefaultValue(t)
   375  	}
   376  
   377  	// Insert the function control frame.
   378  	c.controlFrames.push(controlFrame{
   379  		frameID:   c.nextFrameID(),
   380  		blockType: c.sig,
   381  		kind:      controlFrameKindFunction,
   382  	})
   383  
   384  	// Now, enter the function body.
   385  	for !c.controlFrames.empty() && c.pc < uint64(len(c.body)) {
   386  		if err := c.handleInstruction(); err != nil {
   387  			return fmt.Errorf("handling instruction: %w", err)
   388  		}
   389  	}
   390  	return nil
   391  }
   392  
   393  // Translate the current Wasm instruction to interpreterir's operations,
   394  // and emit the results into c.results.
   395  func (c *compiler) handleInstruction() error {
   396  	op := c.body[c.pc]
   397  	c.currentOpPC = c.pc
   398  	if false {
   399  		var instName string
   400  		if op == wasm.OpcodeVecPrefix {
   401  			instName = wasm.VectorInstructionName(c.body[c.pc+1])
   402  		} else if op == wasm.OpcodeAtomicPrefix {
   403  			instName = wasm.AtomicInstructionName(c.body[c.pc+1])
   404  		} else if op == wasm.OpcodeMiscPrefix {
   405  			instName = wasm.MiscInstructionName(c.body[c.pc+1])
   406  		} else {
   407  			instName = wasm.InstructionName(op)
   408  		}
   409  		fmt.Printf("handling %s, unreachable_state(on=%v,depth=%d), stack=%v\n",
   410  			instName, c.unreachableState.on, c.unreachableState.depth, c.stack,
   411  		)
   412  	}
   413  
   414  	var peekValueType unsignedType
   415  	if len(c.stack) > 0 {
   416  		peekValueType = c.stackPeek()
   417  	}
   418  
   419  	// Modify the stack according the current instruction.
   420  	// Note that some instructions will read "index" in
   421  	// applyToStack and advance c.pc inside the function.
   422  	index, err := c.applyToStack(op)
   423  	if err != nil {
   424  		return fmt.Errorf("apply stack failed for %s: %w", wasm.InstructionName(op), err)
   425  	}
   426  	// Now we handle each instruction, and
   427  	// emit the corresponding interpreterir operations to the results.
   428  operatorSwitch:
   429  	switch op {
   430  	case wasm.OpcodeUnreachable:
   431  		c.emit(newOperationUnreachable())
   432  		c.markUnreachable()
   433  	case wasm.OpcodeNop:
   434  		// Nop is noop!
   435  	case wasm.OpcodeBlock:
   436  		c.br.Reset(c.body[c.pc+1:])
   437  		bt, num, err := wasm.DecodeBlockType(c.types, c.br, c.enabledFeatures)
   438  		if err != nil {
   439  			return fmt.Errorf("reading block type for block instruction: %w", err)
   440  		}
   441  		c.pc += num
   442  
   443  		if c.unreachableState.on {
   444  			// If it is currently in unreachable,
   445  			// just remove the entire block.
   446  			c.unreachableState.depth++
   447  			break operatorSwitch
   448  		}
   449  
   450  		// Create a new frame -- entering this block.
   451  		frame := controlFrame{
   452  			frameID:                      c.nextFrameID(),
   453  			originalStackLenWithoutParam: len(c.stack) - len(bt.Params),
   454  			kind:                         controlFrameKindBlockWithoutContinuationLabel,
   455  			blockType:                    bt,
   456  		}
   457  		c.controlFrames.push(frame)
   458  
   459  	case wasm.OpcodeLoop:
   460  		c.br.Reset(c.body[c.pc+1:])
   461  		bt, num, err := wasm.DecodeBlockType(c.types, c.br, c.enabledFeatures)
   462  		if err != nil {
   463  			return fmt.Errorf("reading block type for loop instruction: %w", err)
   464  		}
   465  		c.pc += num
   466  
   467  		if c.unreachableState.on {
   468  			// If it is currently in unreachable,
   469  			// just remove the entire block.
   470  			c.unreachableState.depth++
   471  			break operatorSwitch
   472  		}
   473  
   474  		// Create a new frame -- entering loop.
   475  		frame := controlFrame{
   476  			frameID:                      c.nextFrameID(),
   477  			originalStackLenWithoutParam: len(c.stack) - len(bt.Params),
   478  			kind:                         controlFrameKindLoop,
   479  			blockType:                    bt,
   480  		}
   481  		c.controlFrames.push(frame)
   482  
   483  		// Prep labels for inside and the continuation of this loop.
   484  		loopLabel := newLabel(labelKindHeader, frame.frameID)
   485  		c.result.LabelCallers[loopLabel]++
   486  
   487  		// Emit the branch operation to enter inside the loop.
   488  		c.emit(newOperationBr(loopLabel))
   489  		c.emit(newOperationLabel(loopLabel))
   490  
   491  		// Insert the exit code check on the loop header, which is the only necessary point in the function body
   492  		// to prevent infinite loop.
   493  		//
   494  		// Note that this is a little aggressive: this checks the exit code regardless the loop header is actually
   495  		// the loop. In other words, this checks even when no br/br_if/br_table instructions jumping to this loop
   496  		// exist. However, in reality, that shouldn't be an issue since such "noop" loop header will highly likely be
   497  		// optimized out by almost all guest language compilers which have the control flow optimization passes.
   498  		if c.ensureTermination {
   499  			c.emit(newOperationBuiltinFunctionCheckExitCode())
   500  		}
   501  	case wasm.OpcodeIf:
   502  		c.br.Reset(c.body[c.pc+1:])
   503  		bt, num, err := wasm.DecodeBlockType(c.types, c.br, c.enabledFeatures)
   504  		if err != nil {
   505  			return fmt.Errorf("reading block type for if instruction: %w", err)
   506  		}
   507  		c.pc += num
   508  
   509  		if c.unreachableState.on {
   510  			// If it is currently in unreachable,
   511  			// just remove the entire block.
   512  			c.unreachableState.depth++
   513  			break operatorSwitch
   514  		}
   515  
   516  		// Create a new frame -- entering if.
   517  		frame := controlFrame{
   518  			frameID:                      c.nextFrameID(),
   519  			originalStackLenWithoutParam: len(c.stack) - len(bt.Params),
   520  			// Note this will be set to controlFrameKindIfWithElse
   521  			// when else opcode found later.
   522  			kind:      controlFrameKindIfWithoutElse,
   523  			blockType: bt,
   524  		}
   525  		c.controlFrames.push(frame)
   526  
   527  		// Prep labels for if and else of this if.
   528  		thenLabel := newLabel(labelKindHeader, frame.frameID)
   529  		elseLabel := newLabel(labelKindElse, frame.frameID)
   530  		c.result.LabelCallers[thenLabel]++
   531  		c.result.LabelCallers[elseLabel]++
   532  
   533  		// Emit the branch operation to enter the then block.
   534  		c.emit(newOperationBrIf(thenLabel, elseLabel, nopinclusiveRange))
   535  		c.emit(newOperationLabel(thenLabel))
   536  	case wasm.OpcodeElse:
   537  		frame := c.controlFrames.top()
   538  		if c.unreachableState.on && c.unreachableState.depth > 0 {
   539  			// If it is currently in unreachable, and the nested if,
   540  			// just remove the entire else block.
   541  			break operatorSwitch
   542  		} else if c.unreachableState.on {
   543  			// If it is currently in unreachable, and the non-nested if,
   544  			// reset the stack so we can correctly handle the else block.
   545  			top := c.controlFrames.top()
   546  			c.stack = c.stack[:top.originalStackLenWithoutParam]
   547  			top.kind = controlFrameKindIfWithElse
   548  
   549  			// Re-push the parameters to the if block so that else block can use them.
   550  			for _, t := range frame.blockType.Params {
   551  				c.stackPush(wasmValueTypeTounsignedType(t))
   552  			}
   553  
   554  			// We are no longer unreachable in else frame,
   555  			// so emit the correct label, and reset the unreachable state.
   556  			elseLabel := newLabel(labelKindElse, frame.frameID)
   557  			c.resetUnreachable()
   558  			c.emit(
   559  				newOperationLabel(elseLabel),
   560  			)
   561  			break operatorSwitch
   562  		}
   563  
   564  		// Change the Kind of this If block, indicating that
   565  		// the if has else block.
   566  		frame.kind = controlFrameKindIfWithElse
   567  
   568  		// We need to reset the stack so that
   569  		// the values pushed inside the then block
   570  		// do not affect the else block.
   571  		dropOp := newOperationDrop(c.getFrameDropRange(frame, false))
   572  
   573  		// Reset the stack manipulated by the then block, and re-push the block param types to the stack.
   574  
   575  		c.stack = c.stack[:frame.originalStackLenWithoutParam]
   576  		for _, t := range frame.blockType.Params {
   577  			c.stackPush(wasmValueTypeTounsignedType(t))
   578  		}
   579  
   580  		// Prep labels for else and the continuation of this if block.
   581  		elseLabel := newLabel(labelKindElse, frame.frameID)
   582  		continuationLabel := newLabel(labelKindContinuation, frame.frameID)
   583  		c.result.LabelCallers[continuationLabel]++
   584  
   585  		// Emit the instructions for exiting the if loop,
   586  		// and then the initiation of else block.
   587  		c.emit(dropOp)
   588  		// Jump to the continuation of this block.
   589  		c.emit(newOperationBr(continuationLabel))
   590  		// Initiate the else block.
   591  		c.emit(newOperationLabel(elseLabel))
   592  	case wasm.OpcodeEnd:
   593  		if c.unreachableState.on && c.unreachableState.depth > 0 {
   594  			c.unreachableState.depth--
   595  			break operatorSwitch
   596  		} else if c.unreachableState.on {
   597  			c.resetUnreachable()
   598  
   599  			frame := c.controlFrames.pop()
   600  			if c.controlFrames.empty() {
   601  				return nil
   602  			}
   603  
   604  			c.stack = c.stack[:frame.originalStackLenWithoutParam]
   605  			for _, t := range frame.blockType.Results {
   606  				c.stackPush(wasmValueTypeTounsignedType(t))
   607  			}
   608  
   609  			continuationLabel := newLabel(labelKindContinuation, frame.frameID)
   610  			if frame.kind == controlFrameKindIfWithoutElse {
   611  				// Emit the else label.
   612  				elseLabel := newLabel(labelKindElse, frame.frameID)
   613  				c.result.LabelCallers[continuationLabel]++
   614  				c.emit(newOperationLabel(elseLabel))
   615  				c.emit(newOperationBr(continuationLabel))
   616  				c.emit(newOperationLabel(continuationLabel))
   617  			} else {
   618  				c.emit(
   619  					newOperationLabel(continuationLabel),
   620  				)
   621  			}
   622  
   623  			break operatorSwitch
   624  		}
   625  
   626  		frame := c.controlFrames.pop()
   627  
   628  		// We need to reset the stack so that
   629  		// the values pushed inside the block.
   630  		dropOp := newOperationDrop(c.getFrameDropRange(frame, true))
   631  		c.stack = c.stack[:frame.originalStackLenWithoutParam]
   632  
   633  		// Push the result types onto the stack.
   634  		for _, t := range frame.blockType.Results {
   635  			c.stackPush(wasmValueTypeTounsignedType(t))
   636  		}
   637  
   638  		// Emit the instructions according to the Kind of the current control frame.
   639  		switch frame.kind {
   640  		case controlFrameKindFunction:
   641  			if !c.controlFrames.empty() {
   642  				// Should never happen. If so, there's a bug in the translation.
   643  				panic("bug: found more function control frames")
   644  			}
   645  			// Return from function.
   646  			c.emit(dropOp)
   647  			c.emit(newOperationBr(newLabel(labelKindReturn, 0)))
   648  		case controlFrameKindIfWithoutElse:
   649  			// This case we have to emit "empty" else label.
   650  			elseLabel := newLabel(labelKindElse, frame.frameID)
   651  			continuationLabel := newLabel(labelKindContinuation, frame.frameID)
   652  			c.result.LabelCallers[continuationLabel] += 2
   653  			c.emit(dropOp)
   654  			c.emit(newOperationBr(continuationLabel))
   655  			// Emit the else which soon branches into the continuation.
   656  			c.emit(newOperationLabel(elseLabel))
   657  			c.emit(newOperationBr(continuationLabel))
   658  			// Initiate the continuation.
   659  			c.emit(newOperationLabel(continuationLabel))
   660  		case controlFrameKindBlockWithContinuationLabel,
   661  			controlFrameKindIfWithElse:
   662  			continuationLabel := newLabel(labelKindContinuation, frame.frameID)
   663  			c.result.LabelCallers[continuationLabel]++
   664  			c.emit(dropOp)
   665  			c.emit(newOperationBr(continuationLabel))
   666  			c.emit(newOperationLabel(continuationLabel))
   667  		case controlFrameKindLoop, controlFrameKindBlockWithoutContinuationLabel:
   668  			c.emit(
   669  				dropOp,
   670  			)
   671  		default:
   672  			// Should never happen. If so, there's a bug in the translation.
   673  			panic(fmt.Errorf("bug: invalid control frame Kind: 0x%x", frame.kind))
   674  		}
   675  
   676  	case wasm.OpcodeBr:
   677  		targetIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:])
   678  		if err != nil {
   679  			return fmt.Errorf("read the target for br_if: %w", err)
   680  		}
   681  		c.pc += n
   682  
   683  		if c.unreachableState.on {
   684  			// If it is currently in unreachable, br is no-op.
   685  			break operatorSwitch
   686  		}
   687  
   688  		targetFrame := c.controlFrames.get(int(targetIndex))
   689  		targetFrame.ensureContinuation()
   690  		dropOp := newOperationDrop(c.getFrameDropRange(targetFrame, false))
   691  		targetID := targetFrame.asLabel()
   692  		c.result.LabelCallers[targetID]++
   693  		c.emit(dropOp)
   694  		c.emit(newOperationBr(targetID))
   695  		// Br operation is stack-polymorphic, and mark the state as unreachable.
   696  		// That means subsequent instructions in the current control frame are "unreachable"
   697  		// and can be safely removed.
   698  		c.markUnreachable()
   699  	case wasm.OpcodeBrIf:
   700  		targetIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:])
   701  		if err != nil {
   702  			return fmt.Errorf("read the target for br_if: %w", err)
   703  		}
   704  		c.pc += n
   705  
   706  		if c.unreachableState.on {
   707  			// If it is currently in unreachable, br-if is no-op.
   708  			break operatorSwitch
   709  		}
   710  
   711  		targetFrame := c.controlFrames.get(int(targetIndex))
   712  		targetFrame.ensureContinuation()
   713  		drop := c.getFrameDropRange(targetFrame, false)
   714  		target := targetFrame.asLabel()
   715  		c.result.LabelCallers[target]++
   716  
   717  		continuationLabel := newLabel(labelKindHeader, c.nextFrameID())
   718  		c.result.LabelCallers[continuationLabel]++
   719  		c.emit(newOperationBrIf(target, continuationLabel, drop))
   720  		// Start emitting else block operations.
   721  		c.emit(newOperationLabel(continuationLabel))
   722  	case wasm.OpcodeBrTable:
   723  		c.br.Reset(c.body[c.pc+1:])
   724  		r := c.br
   725  		numTargets, n, err := leb128.DecodeUint32(r)
   726  		if err != nil {
   727  			return fmt.Errorf("error reading number of targets in br_table: %w", err)
   728  		}
   729  		c.pc += n
   730  
   731  		if c.unreachableState.on {
   732  			// If it is currently in unreachable, br_table is no-op.
   733  			// But before proceeding to the next instruction, we must advance the pc
   734  			// according to the number of br_table targets.
   735  			for i := uint32(0); i <= numTargets; i++ { // inclusive as we also need to read the index of default target.
   736  				_, n, err := leb128.DecodeUint32(r)
   737  				if err != nil {
   738  					return fmt.Errorf("error reading target %d in br_table: %w", i, err)
   739  				}
   740  				c.pc += n
   741  			}
   742  			break operatorSwitch
   743  		}
   744  
   745  		// Read the branch targets.
   746  		s := numTargets * 2
   747  		targetLabels := make([]uint64, 2+s) // (label, inclusiveRange) * (default+numTargets)
   748  		for i := uint32(0); i < s; i += 2 {
   749  			l, n, err := leb128.DecodeUint32(r)
   750  			if err != nil {
   751  				return fmt.Errorf("error reading target %d in br_table: %w", i, err)
   752  			}
   753  			c.pc += n
   754  			targetFrame := c.controlFrames.get(int(l))
   755  			targetFrame.ensureContinuation()
   756  			drop := c.getFrameDropRange(targetFrame, false)
   757  			targetLabel := targetFrame.asLabel()
   758  			targetLabels[i] = uint64(targetLabel)
   759  			targetLabels[i+1] = drop.AsU64()
   760  			c.result.LabelCallers[targetLabel]++
   761  		}
   762  
   763  		// Prep default target control frame.
   764  		l, n, err := leb128.DecodeUint32(r)
   765  		if err != nil {
   766  			return fmt.Errorf("error reading default target of br_table: %w", err)
   767  		}
   768  		c.pc += n
   769  		defaultTargetFrame := c.controlFrames.get(int(l))
   770  		defaultTargetFrame.ensureContinuation()
   771  		defaultTargetDrop := c.getFrameDropRange(defaultTargetFrame, false)
   772  		defaultLabel := defaultTargetFrame.asLabel()
   773  		c.result.LabelCallers[defaultLabel]++
   774  		targetLabels[s] = uint64(defaultLabel)
   775  		targetLabels[s+1] = defaultTargetDrop.AsU64()
   776  		c.emit(newOperationBrTable(targetLabels))
   777  
   778  		// br_table operation is stack-polymorphic, and mark the state as unreachable.
   779  		// That means subsequent instructions in the current control frame are "unreachable"
   780  		// and can be safely removed.
   781  		c.markUnreachable()
   782  	case wasm.OpcodeReturn:
   783  		functionFrame := c.controlFrames.functionFrame()
   784  		dropOp := newOperationDrop(c.getFrameDropRange(functionFrame, false))
   785  
   786  		// Cleanup the stack and then jmp to function frame's continuation (meaning return).
   787  		c.emit(dropOp)
   788  		c.emit(newOperationBr(functionFrame.asLabel()))
   789  
   790  		// Return operation is stack-polymorphic, and mark the state as unreachable.
   791  		// That means subsequent instructions in the current control frame are "unreachable"
   792  		// and can be safely removed.
   793  		c.markUnreachable()
   794  	case wasm.OpcodeCall:
   795  		c.emit(
   796  			newOperationCall(index),
   797  		)
   798  	case wasm.OpcodeCallIndirect:
   799  		typeIndex := index
   800  		tableIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:])
   801  		if err != nil {
   802  			return fmt.Errorf("read target for br_table: %w", err)
   803  		}
   804  		c.pc += n
   805  		c.emit(
   806  			newOperationCallIndirect(typeIndex, tableIndex),
   807  		)
   808  	case wasm.OpcodeDrop:
   809  		r := inclusiveRange{Start: 0, End: 0}
   810  		if peekValueType == unsignedTypeV128 {
   811  			// inclusiveRange is the range in uint64 representation, so dropping a vector value on top
   812  			// should be translated as drop [0..1] inclusively.
   813  			r.End++
   814  		}
   815  		c.emit(newOperationDrop(r))
   816  	case wasm.OpcodeSelect:
   817  		// If it is on the unreachable state, ignore the instruction.
   818  		if c.unreachableState.on {
   819  			break operatorSwitch
   820  		}
   821  		isTargetVector := c.stackPeek() == unsignedTypeV128
   822  		c.emit(
   823  			newOperationSelect(isTargetVector),
   824  		)
   825  	case wasm.OpcodeTypedSelect:
   826  		// Skips two bytes: vector size fixed to 1, and the value type for select.
   827  		c.pc += 2
   828  		// If it is on the unreachable state, ignore the instruction.
   829  		if c.unreachableState.on {
   830  			break operatorSwitch
   831  		}
   832  		// Typed select is semantically equivalent to select at runtime.
   833  		isTargetVector := c.stackPeek() == unsignedTypeV128
   834  		c.emit(
   835  			newOperationSelect(isTargetVector),
   836  		)
   837  	case wasm.OpcodeLocalGet:
   838  		depth := c.localDepth(index)
   839  		if isVector := c.localType(index) == wasm.ValueTypeV128; !isVector {
   840  			c.emit(
   841  				// -1 because we already manipulated the stack before
   842  				// called localDepth ^^.
   843  				newOperationPick(depth-1, isVector),
   844  			)
   845  		} else {
   846  			c.emit(
   847  				// -2 because we already manipulated the stack before
   848  				// called localDepth ^^.
   849  				newOperationPick(depth-2, isVector),
   850  			)
   851  		}
   852  	case wasm.OpcodeLocalSet:
   853  		depth := c.localDepth(index)
   854  
   855  		isVector := c.localType(index) == wasm.ValueTypeV128
   856  		if isVector {
   857  			c.emit(
   858  				// +2 because we already popped the operands for this operation from the c.stack before
   859  				// called localDepth ^^,
   860  				newOperationSet(depth+2, isVector),
   861  			)
   862  		} else {
   863  			c.emit(
   864  				// +1 because we already popped the operands for this operation from the c.stack before
   865  				// called localDepth ^^,
   866  				newOperationSet(depth+1, isVector),
   867  			)
   868  		}
   869  	case wasm.OpcodeLocalTee:
   870  		depth := c.localDepth(index)
   871  		isVector := c.localType(index) == wasm.ValueTypeV128
   872  		if isVector {
   873  			c.emit(newOperationPick(1, isVector))
   874  			c.emit(newOperationSet(depth+2, isVector))
   875  		} else {
   876  			c.emit(
   877  				newOperationPick(0, isVector))
   878  			c.emit(newOperationSet(depth+1, isVector))
   879  		}
   880  	case wasm.OpcodeGlobalGet:
   881  		c.emit(
   882  			newOperationGlobalGet(index),
   883  		)
   884  	case wasm.OpcodeGlobalSet:
   885  		c.emit(
   886  			newOperationGlobalSet(index),
   887  		)
   888  	case wasm.OpcodeI32Load:
   889  		imm, err := c.readMemoryArg(wasm.OpcodeI32LoadName)
   890  		if err != nil {
   891  			return err
   892  		}
   893  		c.emit(newOperationLoad(unsignedTypeI32, imm))
   894  	case wasm.OpcodeI64Load:
   895  		imm, err := c.readMemoryArg(wasm.OpcodeI64LoadName)
   896  		if err != nil {
   897  			return err
   898  		}
   899  		c.emit(newOperationLoad(unsignedTypeI64, imm))
   900  	case wasm.OpcodeF32Load:
   901  		imm, err := c.readMemoryArg(wasm.OpcodeF32LoadName)
   902  		if err != nil {
   903  			return err
   904  		}
   905  		c.emit(newOperationLoad(unsignedTypeF32, imm))
   906  	case wasm.OpcodeF64Load:
   907  		imm, err := c.readMemoryArg(wasm.OpcodeF64LoadName)
   908  		if err != nil {
   909  			return err
   910  		}
   911  		c.emit(newOperationLoad(unsignedTypeF64, imm))
   912  	case wasm.OpcodeI32Load8S:
   913  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load8SName)
   914  		if err != nil {
   915  			return err
   916  		}
   917  		c.emit(newOperationLoad8(signedInt32, imm))
   918  	case wasm.OpcodeI32Load8U:
   919  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load8UName)
   920  		if err != nil {
   921  			return err
   922  		}
   923  		c.emit(newOperationLoad8(signedUint32, imm))
   924  	case wasm.OpcodeI32Load16S:
   925  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load16SName)
   926  		if err != nil {
   927  			return err
   928  		}
   929  		c.emit(newOperationLoad16(signedInt32, imm))
   930  	case wasm.OpcodeI32Load16U:
   931  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load16UName)
   932  		if err != nil {
   933  			return err
   934  		}
   935  		c.emit(newOperationLoad16(signedUint32, imm))
   936  	case wasm.OpcodeI64Load8S:
   937  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load8SName)
   938  		if err != nil {
   939  			return err
   940  		}
   941  		c.emit(newOperationLoad8(signedInt64, imm))
   942  	case wasm.OpcodeI64Load8U:
   943  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load8UName)
   944  		if err != nil {
   945  			return err
   946  		}
   947  		c.emit(newOperationLoad8(signedUint64, imm))
   948  	case wasm.OpcodeI64Load16S:
   949  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load16SName)
   950  		if err != nil {
   951  			return err
   952  		}
   953  		c.emit(newOperationLoad16(signedInt64, imm))
   954  	case wasm.OpcodeI64Load16U:
   955  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load16UName)
   956  		if err != nil {
   957  			return err
   958  		}
   959  		c.emit(newOperationLoad16(signedUint64, imm))
   960  	case wasm.OpcodeI64Load32S:
   961  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load32SName)
   962  		if err != nil {
   963  			return err
   964  		}
   965  		c.emit(newOperationLoad32(true, imm))
   966  	case wasm.OpcodeI64Load32U:
   967  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load32UName)
   968  		if err != nil {
   969  			return err
   970  		}
   971  		c.emit(newOperationLoad32(false, imm))
   972  	case wasm.OpcodeI32Store:
   973  		imm, err := c.readMemoryArg(wasm.OpcodeI32StoreName)
   974  		if err != nil {
   975  			return err
   976  		}
   977  		c.emit(
   978  			newOperationStore(unsignedTypeI32, imm),
   979  		)
   980  	case wasm.OpcodeI64Store:
   981  		imm, err := c.readMemoryArg(wasm.OpcodeI64StoreName)
   982  		if err != nil {
   983  			return err
   984  		}
   985  		c.emit(
   986  			newOperationStore(unsignedTypeI64, imm),
   987  		)
   988  	case wasm.OpcodeF32Store:
   989  		imm, err := c.readMemoryArg(wasm.OpcodeF32StoreName)
   990  		if err != nil {
   991  			return err
   992  		}
   993  		c.emit(
   994  			newOperationStore(unsignedTypeF32, imm),
   995  		)
   996  	case wasm.OpcodeF64Store:
   997  		imm, err := c.readMemoryArg(wasm.OpcodeF64StoreName)
   998  		if err != nil {
   999  			return err
  1000  		}
  1001  		c.emit(
  1002  			newOperationStore(unsignedTypeF64, imm),
  1003  		)
  1004  	case wasm.OpcodeI32Store8:
  1005  		imm, err := c.readMemoryArg(wasm.OpcodeI32Store8Name)
  1006  		if err != nil {
  1007  			return err
  1008  		}
  1009  		c.emit(
  1010  			newOperationStore8(imm),
  1011  		)
  1012  	case wasm.OpcodeI32Store16:
  1013  		imm, err := c.readMemoryArg(wasm.OpcodeI32Store16Name)
  1014  		if err != nil {
  1015  			return err
  1016  		}
  1017  		c.emit(
  1018  			newOperationStore16(imm),
  1019  		)
  1020  	case wasm.OpcodeI64Store8:
  1021  		imm, err := c.readMemoryArg(wasm.OpcodeI64Store8Name)
  1022  		if err != nil {
  1023  			return err
  1024  		}
  1025  		c.emit(
  1026  			newOperationStore8(imm),
  1027  		)
  1028  	case wasm.OpcodeI64Store16:
  1029  		imm, err := c.readMemoryArg(wasm.OpcodeI64Store16Name)
  1030  		if err != nil {
  1031  			return err
  1032  		}
  1033  		c.emit(
  1034  			newOperationStore16(imm),
  1035  		)
  1036  	case wasm.OpcodeI64Store32:
  1037  		imm, err := c.readMemoryArg(wasm.OpcodeI64Store32Name)
  1038  		if err != nil {
  1039  			return err
  1040  		}
  1041  		c.emit(
  1042  			newOperationStore32(imm),
  1043  		)
  1044  	case wasm.OpcodeMemorySize:
  1045  		c.result.UsesMemory = true
  1046  		c.pc++ // Skip the reserved one byte.
  1047  		c.emit(
  1048  			newOperationMemorySize(),
  1049  		)
  1050  	case wasm.OpcodeMemoryGrow:
  1051  		c.result.UsesMemory = true
  1052  		c.pc++ // Skip the reserved one byte.
  1053  		c.emit(
  1054  			newOperationMemoryGrow(),
  1055  		)
  1056  	case wasm.OpcodeI32Const:
  1057  		val, num, err := leb128.LoadInt32(c.body[c.pc+1:])
  1058  		if err != nil {
  1059  			return fmt.Errorf("reading i32.const value: %v", err)
  1060  		}
  1061  		c.pc += num
  1062  		c.emit(
  1063  			newOperationConstI32(uint32(val)),
  1064  		)
  1065  	case wasm.OpcodeI64Const:
  1066  		val, num, err := leb128.LoadInt64(c.body[c.pc+1:])
  1067  		if err != nil {
  1068  			return fmt.Errorf("reading i64.const value: %v", err)
  1069  		}
  1070  		c.pc += num
  1071  		c.emit(
  1072  			newOperationConstI64(uint64(val)),
  1073  		)
  1074  	case wasm.OpcodeF32Const:
  1075  		v := math.Float32frombits(binary.LittleEndian.Uint32(c.body[c.pc+1:]))
  1076  		c.pc += 4
  1077  		c.emit(
  1078  			newOperationConstF32(v),
  1079  		)
  1080  	case wasm.OpcodeF64Const:
  1081  		v := math.Float64frombits(binary.LittleEndian.Uint64(c.body[c.pc+1:]))
  1082  		c.pc += 8
  1083  		c.emit(
  1084  			newOperationConstF64(v),
  1085  		)
  1086  	case wasm.OpcodeI32Eqz:
  1087  		c.emit(
  1088  			newOperationEqz(unsignedInt32),
  1089  		)
  1090  	case wasm.OpcodeI32Eq:
  1091  		c.emit(
  1092  			newOperationEq(unsignedTypeI32),
  1093  		)
  1094  	case wasm.OpcodeI32Ne:
  1095  		c.emit(
  1096  			newOperationNe(unsignedTypeI32),
  1097  		)
  1098  	case wasm.OpcodeI32LtS:
  1099  		c.emit(
  1100  			newOperationLt(signedTypeInt32),
  1101  		)
  1102  	case wasm.OpcodeI32LtU:
  1103  		c.emit(
  1104  			newOperationLt(signedTypeUint32),
  1105  		)
  1106  	case wasm.OpcodeI32GtS:
  1107  		c.emit(
  1108  			newOperationGt(signedTypeInt32),
  1109  		)
  1110  	case wasm.OpcodeI32GtU:
  1111  		c.emit(
  1112  			newOperationGt(signedTypeUint32),
  1113  		)
  1114  	case wasm.OpcodeI32LeS:
  1115  		c.emit(
  1116  			newOperationLe(signedTypeInt32),
  1117  		)
  1118  	case wasm.OpcodeI32LeU:
  1119  		c.emit(
  1120  			newOperationLe(signedTypeUint32),
  1121  		)
  1122  	case wasm.OpcodeI32GeS:
  1123  		c.emit(
  1124  			newOperationGe(signedTypeInt32),
  1125  		)
  1126  	case wasm.OpcodeI32GeU:
  1127  		c.emit(
  1128  			newOperationGe(signedTypeUint32),
  1129  		)
  1130  	case wasm.OpcodeI64Eqz:
  1131  		c.emit(
  1132  			newOperationEqz(unsignedInt64),
  1133  		)
  1134  	case wasm.OpcodeI64Eq:
  1135  		c.emit(
  1136  			newOperationEq(unsignedTypeI64),
  1137  		)
  1138  	case wasm.OpcodeI64Ne:
  1139  		c.emit(
  1140  			newOperationNe(unsignedTypeI64),
  1141  		)
  1142  	case wasm.OpcodeI64LtS:
  1143  		c.emit(
  1144  			newOperationLt(signedTypeInt64),
  1145  		)
  1146  	case wasm.OpcodeI64LtU:
  1147  		c.emit(
  1148  			newOperationLt(signedTypeUint64),
  1149  		)
  1150  	case wasm.OpcodeI64GtS:
  1151  		c.emit(
  1152  			newOperationGt(signedTypeInt64),
  1153  		)
  1154  	case wasm.OpcodeI64GtU:
  1155  		c.emit(
  1156  			newOperationGt(signedTypeUint64),
  1157  		)
  1158  	case wasm.OpcodeI64LeS:
  1159  		c.emit(
  1160  			newOperationLe(signedTypeInt64),
  1161  		)
  1162  	case wasm.OpcodeI64LeU:
  1163  		c.emit(
  1164  			newOperationLe(signedTypeUint64),
  1165  		)
  1166  	case wasm.OpcodeI64GeS:
  1167  		c.emit(
  1168  			newOperationGe(signedTypeInt64),
  1169  		)
  1170  	case wasm.OpcodeI64GeU:
  1171  		c.emit(
  1172  			newOperationGe(signedTypeUint64),
  1173  		)
  1174  	case wasm.OpcodeF32Eq:
  1175  		c.emit(
  1176  			newOperationEq(unsignedTypeF32),
  1177  		)
  1178  	case wasm.OpcodeF32Ne:
  1179  		c.emit(
  1180  			newOperationNe(unsignedTypeF32),
  1181  		)
  1182  	case wasm.OpcodeF32Lt:
  1183  		c.emit(
  1184  			newOperationLt(signedTypeFloat32),
  1185  		)
  1186  	case wasm.OpcodeF32Gt:
  1187  		c.emit(
  1188  			newOperationGt(signedTypeFloat32),
  1189  		)
  1190  	case wasm.OpcodeF32Le:
  1191  		c.emit(
  1192  			newOperationLe(signedTypeFloat32),
  1193  		)
  1194  	case wasm.OpcodeF32Ge:
  1195  		c.emit(
  1196  			newOperationGe(signedTypeFloat32),
  1197  		)
  1198  	case wasm.OpcodeF64Eq:
  1199  		c.emit(
  1200  			newOperationEq(unsignedTypeF64),
  1201  		)
  1202  	case wasm.OpcodeF64Ne:
  1203  		c.emit(
  1204  			newOperationNe(unsignedTypeF64),
  1205  		)
  1206  	case wasm.OpcodeF64Lt:
  1207  		c.emit(
  1208  			newOperationLt(signedTypeFloat64),
  1209  		)
  1210  	case wasm.OpcodeF64Gt:
  1211  		c.emit(
  1212  			newOperationGt(signedTypeFloat64),
  1213  		)
  1214  	case wasm.OpcodeF64Le:
  1215  		c.emit(
  1216  			newOperationLe(signedTypeFloat64),
  1217  		)
  1218  	case wasm.OpcodeF64Ge:
  1219  		c.emit(
  1220  			newOperationGe(signedTypeFloat64),
  1221  		)
  1222  	case wasm.OpcodeI32Clz:
  1223  		c.emit(
  1224  			newOperationClz(unsignedInt32),
  1225  		)
  1226  	case wasm.OpcodeI32Ctz:
  1227  		c.emit(
  1228  			newOperationCtz(unsignedInt32),
  1229  		)
  1230  	case wasm.OpcodeI32Popcnt:
  1231  		c.emit(
  1232  			newOperationPopcnt(unsignedInt32),
  1233  		)
  1234  	case wasm.OpcodeI32Add:
  1235  		c.emit(
  1236  			newOperationAdd(unsignedTypeI32),
  1237  		)
  1238  	case wasm.OpcodeI32Sub:
  1239  		c.emit(
  1240  			newOperationSub(unsignedTypeI32),
  1241  		)
  1242  	case wasm.OpcodeI32Mul:
  1243  		c.emit(
  1244  			newOperationMul(unsignedTypeI32),
  1245  		)
  1246  	case wasm.OpcodeI32DivS:
  1247  		c.emit(
  1248  			newOperationDiv(signedTypeInt32),
  1249  		)
  1250  	case wasm.OpcodeI32DivU:
  1251  		c.emit(
  1252  			newOperationDiv(signedTypeUint32),
  1253  		)
  1254  	case wasm.OpcodeI32RemS:
  1255  		c.emit(
  1256  			newOperationRem(signedInt32),
  1257  		)
  1258  	case wasm.OpcodeI32RemU:
  1259  		c.emit(
  1260  			newOperationRem(signedUint32),
  1261  		)
  1262  	case wasm.OpcodeI32And:
  1263  		c.emit(
  1264  			newOperationAnd(unsignedInt32),
  1265  		)
  1266  	case wasm.OpcodeI32Or:
  1267  		c.emit(
  1268  			newOperationOr(unsignedInt32),
  1269  		)
  1270  	case wasm.OpcodeI32Xor:
  1271  		c.emit(
  1272  			newOperationXor(unsignedInt64),
  1273  		)
  1274  	case wasm.OpcodeI32Shl:
  1275  		c.emit(
  1276  			newOperationShl(unsignedInt32),
  1277  		)
  1278  	case wasm.OpcodeI32ShrS:
  1279  		c.emit(
  1280  			newOperationShr(signedInt32),
  1281  		)
  1282  	case wasm.OpcodeI32ShrU:
  1283  		c.emit(
  1284  			newOperationShr(signedUint32),
  1285  		)
  1286  	case wasm.OpcodeI32Rotl:
  1287  		c.emit(
  1288  			newOperationRotl(unsignedInt32),
  1289  		)
  1290  	case wasm.OpcodeI32Rotr:
  1291  		c.emit(
  1292  			newOperationRotr(unsignedInt32),
  1293  		)
  1294  	case wasm.OpcodeI64Clz:
  1295  		c.emit(
  1296  			newOperationClz(unsignedInt64),
  1297  		)
  1298  	case wasm.OpcodeI64Ctz:
  1299  		c.emit(
  1300  			newOperationCtz(unsignedInt64),
  1301  		)
  1302  	case wasm.OpcodeI64Popcnt:
  1303  		c.emit(
  1304  			newOperationPopcnt(unsignedInt64),
  1305  		)
  1306  	case wasm.OpcodeI64Add:
  1307  		c.emit(
  1308  			newOperationAdd(unsignedTypeI64),
  1309  		)
  1310  	case wasm.OpcodeI64Sub:
  1311  		c.emit(
  1312  			newOperationSub(unsignedTypeI64),
  1313  		)
  1314  	case wasm.OpcodeI64Mul:
  1315  		c.emit(
  1316  			newOperationMul(unsignedTypeI64),
  1317  		)
  1318  	case wasm.OpcodeI64DivS:
  1319  		c.emit(
  1320  			newOperationDiv(signedTypeInt64),
  1321  		)
  1322  	case wasm.OpcodeI64DivU:
  1323  		c.emit(
  1324  			newOperationDiv(signedTypeUint64),
  1325  		)
  1326  	case wasm.OpcodeI64RemS:
  1327  		c.emit(
  1328  			newOperationRem(signedInt64),
  1329  		)
  1330  	case wasm.OpcodeI64RemU:
  1331  		c.emit(
  1332  			newOperationRem(signedUint64),
  1333  		)
  1334  	case wasm.OpcodeI64And:
  1335  		c.emit(
  1336  			newOperationAnd(unsignedInt64),
  1337  		)
  1338  	case wasm.OpcodeI64Or:
  1339  		c.emit(
  1340  			newOperationOr(unsignedInt64),
  1341  		)
  1342  	case wasm.OpcodeI64Xor:
  1343  		c.emit(
  1344  			newOperationXor(unsignedInt64),
  1345  		)
  1346  	case wasm.OpcodeI64Shl:
  1347  		c.emit(
  1348  			newOperationShl(unsignedInt64),
  1349  		)
  1350  	case wasm.OpcodeI64ShrS:
  1351  		c.emit(
  1352  			newOperationShr(signedInt64),
  1353  		)
  1354  	case wasm.OpcodeI64ShrU:
  1355  		c.emit(
  1356  			newOperationShr(signedUint64),
  1357  		)
  1358  	case wasm.OpcodeI64Rotl:
  1359  		c.emit(
  1360  			newOperationRotl(unsignedInt64),
  1361  		)
  1362  	case wasm.OpcodeI64Rotr:
  1363  		c.emit(
  1364  			newOperationRotr(unsignedInt64),
  1365  		)
  1366  	case wasm.OpcodeF32Abs:
  1367  		c.emit(
  1368  			newOperationAbs(f32),
  1369  		)
  1370  	case wasm.OpcodeF32Neg:
  1371  		c.emit(
  1372  			newOperationNeg(f32),
  1373  		)
  1374  	case wasm.OpcodeF32Ceil:
  1375  		c.emit(
  1376  			newOperationCeil(f32),
  1377  		)
  1378  	case wasm.OpcodeF32Floor:
  1379  		c.emit(
  1380  			newOperationFloor(f32),
  1381  		)
  1382  	case wasm.OpcodeF32Trunc:
  1383  		c.emit(
  1384  			newOperationTrunc(f32),
  1385  		)
  1386  	case wasm.OpcodeF32Nearest:
  1387  		c.emit(
  1388  			newOperationNearest(f32),
  1389  		)
  1390  	case wasm.OpcodeF32Sqrt:
  1391  		c.emit(
  1392  			newOperationSqrt(f32),
  1393  		)
  1394  	case wasm.OpcodeF32Add:
  1395  		c.emit(
  1396  			newOperationAdd(unsignedTypeF32),
  1397  		)
  1398  	case wasm.OpcodeF32Sub:
  1399  		c.emit(
  1400  			newOperationSub(unsignedTypeF32),
  1401  		)
  1402  	case wasm.OpcodeF32Mul:
  1403  		c.emit(
  1404  			newOperationMul(unsignedTypeF32),
  1405  		)
  1406  	case wasm.OpcodeF32Div:
  1407  		c.emit(
  1408  			newOperationDiv(signedTypeFloat32),
  1409  		)
  1410  	case wasm.OpcodeF32Min:
  1411  		c.emit(
  1412  			newOperationMin(f32),
  1413  		)
  1414  	case wasm.OpcodeF32Max:
  1415  		c.emit(
  1416  			newOperationMax(f32),
  1417  		)
  1418  	case wasm.OpcodeF32Copysign:
  1419  		c.emit(
  1420  			newOperationCopysign(f32),
  1421  		)
  1422  	case wasm.OpcodeF64Abs:
  1423  		c.emit(
  1424  			newOperationAbs(f64),
  1425  		)
  1426  	case wasm.OpcodeF64Neg:
  1427  		c.emit(
  1428  			newOperationNeg(f64),
  1429  		)
  1430  	case wasm.OpcodeF64Ceil:
  1431  		c.emit(
  1432  			newOperationCeil(f64),
  1433  		)
  1434  	case wasm.OpcodeF64Floor:
  1435  		c.emit(
  1436  			newOperationFloor(f64),
  1437  		)
  1438  	case wasm.OpcodeF64Trunc:
  1439  		c.emit(
  1440  			newOperationTrunc(f64),
  1441  		)
  1442  	case wasm.OpcodeF64Nearest:
  1443  		c.emit(
  1444  			newOperationNearest(f64),
  1445  		)
  1446  	case wasm.OpcodeF64Sqrt:
  1447  		c.emit(
  1448  			newOperationSqrt(f64),
  1449  		)
  1450  	case wasm.OpcodeF64Add:
  1451  		c.emit(
  1452  			newOperationAdd(unsignedTypeF64),
  1453  		)
  1454  	case wasm.OpcodeF64Sub:
  1455  		c.emit(
  1456  			newOperationSub(unsignedTypeF64),
  1457  		)
  1458  	case wasm.OpcodeF64Mul:
  1459  		c.emit(
  1460  			newOperationMul(unsignedTypeF64),
  1461  		)
  1462  	case wasm.OpcodeF64Div:
  1463  		c.emit(
  1464  			newOperationDiv(signedTypeFloat64),
  1465  		)
  1466  	case wasm.OpcodeF64Min:
  1467  		c.emit(
  1468  			newOperationMin(f64),
  1469  		)
  1470  	case wasm.OpcodeF64Max:
  1471  		c.emit(
  1472  			newOperationMax(f64),
  1473  		)
  1474  	case wasm.OpcodeF64Copysign:
  1475  		c.emit(
  1476  			newOperationCopysign(f64),
  1477  		)
  1478  	case wasm.OpcodeI32WrapI64:
  1479  		c.emit(
  1480  			newOperationI32WrapFromI64(),
  1481  		)
  1482  	case wasm.OpcodeI32TruncF32S:
  1483  		c.emit(
  1484  			newOperationITruncFromF(f32, signedInt32, false),
  1485  		)
  1486  	case wasm.OpcodeI32TruncF32U:
  1487  		c.emit(
  1488  			newOperationITruncFromF(f32, signedUint32, false),
  1489  		)
  1490  	case wasm.OpcodeI32TruncF64S:
  1491  		c.emit(
  1492  			newOperationITruncFromF(f64, signedInt32, false),
  1493  		)
  1494  	case wasm.OpcodeI32TruncF64U:
  1495  		c.emit(
  1496  			newOperationITruncFromF(f64, signedUint32, false),
  1497  		)
  1498  	case wasm.OpcodeI64ExtendI32S:
  1499  		c.emit(
  1500  			newOperationExtend(true),
  1501  		)
  1502  	case wasm.OpcodeI64ExtendI32U:
  1503  		c.emit(
  1504  			newOperationExtend(false),
  1505  		)
  1506  	case wasm.OpcodeI64TruncF32S:
  1507  		c.emit(
  1508  			newOperationITruncFromF(f32, signedInt64, false),
  1509  		)
  1510  	case wasm.OpcodeI64TruncF32U:
  1511  		c.emit(
  1512  			newOperationITruncFromF(f32, signedUint64, false),
  1513  		)
  1514  	case wasm.OpcodeI64TruncF64S:
  1515  		c.emit(
  1516  			newOperationITruncFromF(f64, signedInt64, false),
  1517  		)
  1518  	case wasm.OpcodeI64TruncF64U:
  1519  		c.emit(
  1520  			newOperationITruncFromF(f64, signedUint64, false),
  1521  		)
  1522  	case wasm.OpcodeF32ConvertI32S:
  1523  		c.emit(
  1524  			newOperationFConvertFromI(signedInt32, f32),
  1525  		)
  1526  	case wasm.OpcodeF32ConvertI32U:
  1527  		c.emit(
  1528  			newOperationFConvertFromI(signedUint32, f32),
  1529  		)
  1530  	case wasm.OpcodeF32ConvertI64S:
  1531  		c.emit(
  1532  			newOperationFConvertFromI(signedInt64, f32),
  1533  		)
  1534  	case wasm.OpcodeF32ConvertI64U:
  1535  		c.emit(
  1536  			newOperationFConvertFromI(signedUint64, f32),
  1537  		)
  1538  	case wasm.OpcodeF32DemoteF64:
  1539  		c.emit(
  1540  			newOperationF32DemoteFromF64(),
  1541  		)
  1542  	case wasm.OpcodeF64ConvertI32S:
  1543  		c.emit(
  1544  			newOperationFConvertFromI(signedInt32, f64),
  1545  		)
  1546  	case wasm.OpcodeF64ConvertI32U:
  1547  		c.emit(
  1548  			newOperationFConvertFromI(signedUint32, f64),
  1549  		)
  1550  	case wasm.OpcodeF64ConvertI64S:
  1551  		c.emit(
  1552  			newOperationFConvertFromI(signedInt64, f64),
  1553  		)
  1554  	case wasm.OpcodeF64ConvertI64U:
  1555  		c.emit(
  1556  			newOperationFConvertFromI(signedUint64, f64),
  1557  		)
  1558  	case wasm.OpcodeF64PromoteF32:
  1559  		c.emit(
  1560  			newOperationF64PromoteFromF32(),
  1561  		)
  1562  	case wasm.OpcodeI32ReinterpretF32:
  1563  		c.emit(
  1564  			newOperationI32ReinterpretFromF32(),
  1565  		)
  1566  	case wasm.OpcodeI64ReinterpretF64:
  1567  		c.emit(
  1568  			newOperationI64ReinterpretFromF64(),
  1569  		)
  1570  	case wasm.OpcodeF32ReinterpretI32:
  1571  		c.emit(
  1572  			newOperationF32ReinterpretFromI32(),
  1573  		)
  1574  	case wasm.OpcodeF64ReinterpretI64:
  1575  		c.emit(
  1576  			newOperationF64ReinterpretFromI64(),
  1577  		)
  1578  	case wasm.OpcodeI32Extend8S:
  1579  		c.emit(
  1580  			newOperationSignExtend32From8(),
  1581  		)
  1582  	case wasm.OpcodeI32Extend16S:
  1583  		c.emit(
  1584  			newOperationSignExtend32From16(),
  1585  		)
  1586  	case wasm.OpcodeI64Extend8S:
  1587  		c.emit(
  1588  			newOperationSignExtend64From8(),
  1589  		)
  1590  	case wasm.OpcodeI64Extend16S:
  1591  		c.emit(
  1592  			newOperationSignExtend64From16(),
  1593  		)
  1594  	case wasm.OpcodeI64Extend32S:
  1595  		c.emit(
  1596  			newOperationSignExtend64From32(),
  1597  		)
  1598  	case wasm.OpcodeRefFunc:
  1599  		c.pc++
  1600  		index, num, err := leb128.LoadUint32(c.body[c.pc:])
  1601  		if err != nil {
  1602  			return fmt.Errorf("failed to read function index for ref.func: %v", err)
  1603  		}
  1604  		c.pc += num - 1
  1605  		c.emit(
  1606  			newOperationRefFunc(index),
  1607  		)
  1608  	case wasm.OpcodeRefNull:
  1609  		c.pc++ // Skip the type of reftype as every ref value is opaque pointer.
  1610  		c.emit(
  1611  			newOperationConstI64(0),
  1612  		)
  1613  	case wasm.OpcodeRefIsNull:
  1614  		// Simply compare the opaque pointer (i64) with zero.
  1615  		c.emit(
  1616  			newOperationEqz(unsignedInt64),
  1617  		)
  1618  	case wasm.OpcodeTableGet:
  1619  		c.pc++
  1620  		tableIndex, num, err := leb128.LoadUint32(c.body[c.pc:])
  1621  		if err != nil {
  1622  			return fmt.Errorf("failed to read function index for table.get: %v", err)
  1623  		}
  1624  		c.pc += num - 1
  1625  		c.emit(
  1626  			newOperationTableGet(tableIndex),
  1627  		)
  1628  	case wasm.OpcodeTableSet:
  1629  		c.pc++
  1630  		tableIndex, num, err := leb128.LoadUint32(c.body[c.pc:])
  1631  		if err != nil {
  1632  			return fmt.Errorf("failed to read function index for table.set: %v", err)
  1633  		}
  1634  		c.pc += num - 1
  1635  		c.emit(
  1636  			newOperationTableSet(tableIndex),
  1637  		)
  1638  	case wasm.OpcodeMiscPrefix:
  1639  		c.pc++
  1640  		// A misc opcode is encoded as an unsigned variable 32-bit integer.
  1641  		miscOp, num, err := leb128.LoadUint32(c.body[c.pc:])
  1642  		if err != nil {
  1643  			return fmt.Errorf("failed to read misc opcode: %v", err)
  1644  		}
  1645  		c.pc += num - 1
  1646  		switch byte(miscOp) {
  1647  		case wasm.OpcodeMiscI32TruncSatF32S:
  1648  			c.emit(
  1649  				newOperationITruncFromF(f32, signedInt32, true),
  1650  			)
  1651  		case wasm.OpcodeMiscI32TruncSatF32U:
  1652  			c.emit(
  1653  				newOperationITruncFromF(f32, signedUint32, true),
  1654  			)
  1655  		case wasm.OpcodeMiscI32TruncSatF64S:
  1656  			c.emit(
  1657  				newOperationITruncFromF(f64, signedInt32, true),
  1658  			)
  1659  		case wasm.OpcodeMiscI32TruncSatF64U:
  1660  			c.emit(
  1661  				newOperationITruncFromF(f64, signedUint32, true),
  1662  			)
  1663  		case wasm.OpcodeMiscI64TruncSatF32S:
  1664  			c.emit(
  1665  				newOperationITruncFromF(f32, signedInt64, true),
  1666  			)
  1667  		case wasm.OpcodeMiscI64TruncSatF32U:
  1668  			c.emit(
  1669  				newOperationITruncFromF(f32, signedUint64, true),
  1670  			)
  1671  		case wasm.OpcodeMiscI64TruncSatF64S:
  1672  			c.emit(
  1673  				newOperationITruncFromF(f64, signedInt64, true),
  1674  			)
  1675  		case wasm.OpcodeMiscI64TruncSatF64U:
  1676  			c.emit(
  1677  				newOperationITruncFromF(f64, signedUint64, true),
  1678  			)
  1679  		case wasm.OpcodeMiscMemoryInit:
  1680  			c.result.UsesMemory = true
  1681  			dataIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1682  			if err != nil {
  1683  				return fmt.Errorf("reading i32.const value: %v", err)
  1684  			}
  1685  			c.pc += num + 1 // +1 to skip the memory index which is fixed to zero.
  1686  			c.emit(
  1687  				newOperationMemoryInit(dataIndex),
  1688  			)
  1689  		case wasm.OpcodeMiscDataDrop:
  1690  			dataIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1691  			if err != nil {
  1692  				return fmt.Errorf("reading i32.const value: %v", err)
  1693  			}
  1694  			c.pc += num
  1695  			c.emit(
  1696  				newOperationDataDrop(dataIndex),
  1697  			)
  1698  		case wasm.OpcodeMiscMemoryCopy:
  1699  			c.result.UsesMemory = true
  1700  			c.pc += 2 // +2 to skip two memory indexes which are fixed to zero.
  1701  			c.emit(
  1702  				newOperationMemoryCopy(),
  1703  			)
  1704  		case wasm.OpcodeMiscMemoryFill:
  1705  			c.result.UsesMemory = true
  1706  			c.pc += 1 // +1 to skip the memory index which is fixed to zero.
  1707  			c.emit(
  1708  				newOperationMemoryFill(),
  1709  			)
  1710  		case wasm.OpcodeMiscTableInit:
  1711  			elemIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1712  			if err != nil {
  1713  				return fmt.Errorf("reading i32.const value: %v", err)
  1714  			}
  1715  			c.pc += num
  1716  			// Read table index which is fixed to zero currently.
  1717  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1718  			if err != nil {
  1719  				return fmt.Errorf("reading i32.const value: %v", err)
  1720  			}
  1721  			c.pc += num
  1722  			c.emit(
  1723  				newOperationTableInit(elemIndex, tableIndex),
  1724  			)
  1725  		case wasm.OpcodeMiscElemDrop:
  1726  			elemIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1727  			if err != nil {
  1728  				return fmt.Errorf("reading i32.const value: %v", err)
  1729  			}
  1730  			c.pc += num
  1731  			c.emit(
  1732  				newOperationElemDrop(elemIndex),
  1733  			)
  1734  		case wasm.OpcodeMiscTableCopy:
  1735  			// Read the source table inde.g.
  1736  			dst, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1737  			if err != nil {
  1738  				return fmt.Errorf("reading i32.const value: %v", err)
  1739  			}
  1740  			c.pc += num
  1741  			// Read the destination table inde.g.
  1742  			src, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1743  			if err != nil {
  1744  				return fmt.Errorf("reading i32.const value: %v", err)
  1745  			}
  1746  			c.pc += num
  1747  			c.emit(
  1748  				newOperationTableCopy(src, dst),
  1749  			)
  1750  		case wasm.OpcodeMiscTableGrow:
  1751  			// Read the source table inde.g.
  1752  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1753  			if err != nil {
  1754  				return fmt.Errorf("reading i32.const value: %v", err)
  1755  			}
  1756  			c.pc += num
  1757  			c.emit(
  1758  				newOperationTableGrow(tableIndex),
  1759  			)
  1760  		case wasm.OpcodeMiscTableSize:
  1761  			// Read the source table inde.g.
  1762  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1763  			if err != nil {
  1764  				return fmt.Errorf("reading i32.const value: %v", err)
  1765  			}
  1766  			c.pc += num
  1767  			c.emit(
  1768  				newOperationTableSize(tableIndex),
  1769  			)
  1770  		case wasm.OpcodeMiscTableFill:
  1771  			// Read the source table index.
  1772  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1773  			if err != nil {
  1774  				return fmt.Errorf("reading i32.const value: %v", err)
  1775  			}
  1776  			c.pc += num
  1777  			c.emit(
  1778  				newOperationTableFill(tableIndex),
  1779  			)
  1780  		default:
  1781  			return fmt.Errorf("unsupported misc instruction in interpreterir: 0x%x", op)
  1782  		}
  1783  	case wasm.OpcodeVecPrefix:
  1784  		c.pc++
  1785  		switch vecOp := c.body[c.pc]; vecOp {
  1786  		case wasm.OpcodeVecV128Const:
  1787  			c.pc++
  1788  			lo := binary.LittleEndian.Uint64(c.body[c.pc : c.pc+8])
  1789  			c.pc += 8
  1790  			hi := binary.LittleEndian.Uint64(c.body[c.pc : c.pc+8])
  1791  			c.emit(
  1792  				newOperationV128Const(lo, hi),
  1793  			)
  1794  			c.pc += 7
  1795  		case wasm.OpcodeVecV128Load:
  1796  			arg, err := c.readMemoryArg(wasm.OpcodeI32LoadName)
  1797  			if err != nil {
  1798  				return err
  1799  			}
  1800  			c.emit(
  1801  				newOperationV128Load(v128LoadType128, arg),
  1802  			)
  1803  		case wasm.OpcodeVecV128Load8x8s:
  1804  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8x8SName)
  1805  			if err != nil {
  1806  				return err
  1807  			}
  1808  			c.emit(
  1809  				newOperationV128Load(v128LoadType8x8s, arg),
  1810  			)
  1811  		case wasm.OpcodeVecV128Load8x8u:
  1812  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8x8UName)
  1813  			if err != nil {
  1814  				return err
  1815  			}
  1816  			c.emit(
  1817  				newOperationV128Load(v128LoadType8x8u, arg),
  1818  			)
  1819  		case wasm.OpcodeVecV128Load16x4s:
  1820  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16x4SName)
  1821  			if err != nil {
  1822  				return err
  1823  			}
  1824  			c.emit(
  1825  				newOperationV128Load(v128LoadType16x4s, arg),
  1826  			)
  1827  		case wasm.OpcodeVecV128Load16x4u:
  1828  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16x4UName)
  1829  			if err != nil {
  1830  				return err
  1831  			}
  1832  			c.emit(
  1833  				newOperationV128Load(v128LoadType16x4u, arg),
  1834  			)
  1835  		case wasm.OpcodeVecV128Load32x2s:
  1836  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32x2SName)
  1837  			if err != nil {
  1838  				return err
  1839  			}
  1840  			c.emit(
  1841  				newOperationV128Load(v128LoadType32x2s, arg),
  1842  			)
  1843  		case wasm.OpcodeVecV128Load32x2u:
  1844  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32x2UName)
  1845  			if err != nil {
  1846  				return err
  1847  			}
  1848  			c.emit(
  1849  				newOperationV128Load(v128LoadType32x2u, arg),
  1850  			)
  1851  		case wasm.OpcodeVecV128Load8Splat:
  1852  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8SplatName)
  1853  			if err != nil {
  1854  				return err
  1855  			}
  1856  			c.emit(
  1857  				newOperationV128Load(v128LoadType8Splat, arg),
  1858  			)
  1859  		case wasm.OpcodeVecV128Load16Splat:
  1860  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16SplatName)
  1861  			if err != nil {
  1862  				return err
  1863  			}
  1864  			c.emit(
  1865  				newOperationV128Load(v128LoadType16Splat, arg),
  1866  			)
  1867  		case wasm.OpcodeVecV128Load32Splat:
  1868  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32SplatName)
  1869  			if err != nil {
  1870  				return err
  1871  			}
  1872  			c.emit(
  1873  				newOperationV128Load(v128LoadType32Splat, arg),
  1874  			)
  1875  		case wasm.OpcodeVecV128Load64Splat:
  1876  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load64SplatName)
  1877  			if err != nil {
  1878  				return err
  1879  			}
  1880  			c.emit(
  1881  				newOperationV128Load(v128LoadType64Splat, arg),
  1882  			)
  1883  		case wasm.OpcodeVecV128Load32zero:
  1884  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32zeroName)
  1885  			if err != nil {
  1886  				return err
  1887  			}
  1888  			c.emit(
  1889  				newOperationV128Load(v128LoadType32zero, arg),
  1890  			)
  1891  		case wasm.OpcodeVecV128Load64zero:
  1892  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load64zeroName)
  1893  			if err != nil {
  1894  				return err
  1895  			}
  1896  			c.emit(
  1897  				newOperationV128Load(v128LoadType64zero, arg),
  1898  			)
  1899  		case wasm.OpcodeVecV128Load8Lane:
  1900  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8LaneName)
  1901  			if err != nil {
  1902  				return err
  1903  			}
  1904  			c.pc++
  1905  			laneIndex := c.body[c.pc]
  1906  			c.emit(
  1907  				newOperationV128LoadLane(laneIndex, 8, arg),
  1908  			)
  1909  		case wasm.OpcodeVecV128Load16Lane:
  1910  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16LaneName)
  1911  			if err != nil {
  1912  				return err
  1913  			}
  1914  			c.pc++
  1915  			laneIndex := c.body[c.pc]
  1916  			c.emit(
  1917  				newOperationV128LoadLane(laneIndex, 16, arg),
  1918  			)
  1919  		case wasm.OpcodeVecV128Load32Lane:
  1920  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32LaneName)
  1921  			if err != nil {
  1922  				return err
  1923  			}
  1924  			c.pc++
  1925  			laneIndex := c.body[c.pc]
  1926  			c.emit(
  1927  				newOperationV128LoadLane(laneIndex, 32, arg),
  1928  			)
  1929  		case wasm.OpcodeVecV128Load64Lane:
  1930  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load64LaneName)
  1931  			if err != nil {
  1932  				return err
  1933  			}
  1934  			c.pc++
  1935  			laneIndex := c.body[c.pc]
  1936  			c.emit(
  1937  				newOperationV128LoadLane(laneIndex, 64, arg),
  1938  			)
  1939  		case wasm.OpcodeVecV128Store:
  1940  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128StoreName)
  1941  			if err != nil {
  1942  				return err
  1943  			}
  1944  			c.emit(
  1945  				newOperationV128Store(arg),
  1946  			)
  1947  		case wasm.OpcodeVecV128Store8Lane:
  1948  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store8LaneName)
  1949  			if err != nil {
  1950  				return err
  1951  			}
  1952  			c.pc++
  1953  			laneIndex := c.body[c.pc]
  1954  			c.emit(
  1955  				newOperationV128StoreLane(laneIndex, 8, arg),
  1956  			)
  1957  		case wasm.OpcodeVecV128Store16Lane:
  1958  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store16LaneName)
  1959  			if err != nil {
  1960  				return err
  1961  			}
  1962  			c.pc++
  1963  			laneIndex := c.body[c.pc]
  1964  			c.emit(
  1965  				newOperationV128StoreLane(laneIndex, 16, arg),
  1966  			)
  1967  		case wasm.OpcodeVecV128Store32Lane:
  1968  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store32LaneName)
  1969  			if err != nil {
  1970  				return err
  1971  			}
  1972  			c.pc++
  1973  			laneIndex := c.body[c.pc]
  1974  			c.emit(
  1975  				newOperationV128StoreLane(laneIndex, 32, arg),
  1976  			)
  1977  		case wasm.OpcodeVecV128Store64Lane:
  1978  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store64LaneName)
  1979  			if err != nil {
  1980  				return err
  1981  			}
  1982  			c.pc++
  1983  			laneIndex := c.body[c.pc]
  1984  			c.emit(
  1985  				newOperationV128StoreLane(laneIndex, 64, arg),
  1986  			)
  1987  		case wasm.OpcodeVecI8x16ExtractLaneS:
  1988  			c.pc++
  1989  			laneIndex := c.body[c.pc]
  1990  			c.emit(
  1991  				newOperationV128ExtractLane(laneIndex, true, shapeI8x16),
  1992  			)
  1993  		case wasm.OpcodeVecI8x16ExtractLaneU:
  1994  			c.pc++
  1995  			laneIndex := c.body[c.pc]
  1996  			c.emit(
  1997  				newOperationV128ExtractLane(laneIndex, false, shapeI8x16),
  1998  			)
  1999  		case wasm.OpcodeVecI16x8ExtractLaneS:
  2000  			c.pc++
  2001  			laneIndex := c.body[c.pc]
  2002  			c.emit(
  2003  				newOperationV128ExtractLane(laneIndex, true, shapeI16x8),
  2004  			)
  2005  		case wasm.OpcodeVecI16x8ExtractLaneU:
  2006  			c.pc++
  2007  			laneIndex := c.body[c.pc]
  2008  			c.emit(
  2009  				newOperationV128ExtractLane(laneIndex, false, shapeI16x8),
  2010  			)
  2011  		case wasm.OpcodeVecI32x4ExtractLane:
  2012  			c.pc++
  2013  			laneIndex := c.body[c.pc]
  2014  			c.emit(
  2015  				newOperationV128ExtractLane(laneIndex, false, shapeI32x4),
  2016  			)
  2017  		case wasm.OpcodeVecI64x2ExtractLane:
  2018  			c.pc++
  2019  			laneIndex := c.body[c.pc]
  2020  			c.emit(
  2021  				newOperationV128ExtractLane(laneIndex, false, shapeI64x2),
  2022  			)
  2023  		case wasm.OpcodeVecF32x4ExtractLane:
  2024  			c.pc++
  2025  			laneIndex := c.body[c.pc]
  2026  			c.emit(
  2027  				newOperationV128ExtractLane(laneIndex, false, shapeF32x4),
  2028  			)
  2029  		case wasm.OpcodeVecF64x2ExtractLane:
  2030  			c.pc++
  2031  			laneIndex := c.body[c.pc]
  2032  			c.emit(
  2033  				newOperationV128ExtractLane(laneIndex, false, shapeF64x2),
  2034  			)
  2035  		case wasm.OpcodeVecI8x16ReplaceLane:
  2036  			c.pc++
  2037  			laneIndex := c.body[c.pc]
  2038  			c.emit(
  2039  				newOperationV128ReplaceLane(laneIndex, shapeI8x16),
  2040  			)
  2041  		case wasm.OpcodeVecI16x8ReplaceLane:
  2042  			c.pc++
  2043  			laneIndex := c.body[c.pc]
  2044  			c.emit(
  2045  				newOperationV128ReplaceLane(laneIndex, shapeI16x8),
  2046  			)
  2047  		case wasm.OpcodeVecI32x4ReplaceLane:
  2048  			c.pc++
  2049  			laneIndex := c.body[c.pc]
  2050  			c.emit(
  2051  				newOperationV128ReplaceLane(laneIndex, shapeI32x4),
  2052  			)
  2053  		case wasm.OpcodeVecI64x2ReplaceLane:
  2054  			c.pc++
  2055  			laneIndex := c.body[c.pc]
  2056  			c.emit(
  2057  				newOperationV128ReplaceLane(laneIndex, shapeI64x2),
  2058  			)
  2059  		case wasm.OpcodeVecF32x4ReplaceLane:
  2060  			c.pc++
  2061  			laneIndex := c.body[c.pc]
  2062  			c.emit(
  2063  				newOperationV128ReplaceLane(laneIndex, shapeF32x4),
  2064  			)
  2065  		case wasm.OpcodeVecF64x2ReplaceLane:
  2066  			c.pc++
  2067  			laneIndex := c.body[c.pc]
  2068  			c.emit(
  2069  				newOperationV128ReplaceLane(laneIndex, shapeF64x2),
  2070  			)
  2071  		case wasm.OpcodeVecI8x16Splat:
  2072  			c.emit(
  2073  				newOperationV128Splat(shapeI8x16),
  2074  			)
  2075  		case wasm.OpcodeVecI16x8Splat:
  2076  			c.emit(
  2077  				newOperationV128Splat(shapeI16x8),
  2078  			)
  2079  		case wasm.OpcodeVecI32x4Splat:
  2080  			c.emit(
  2081  				newOperationV128Splat(shapeI32x4),
  2082  			)
  2083  		case wasm.OpcodeVecI64x2Splat:
  2084  			c.emit(
  2085  				newOperationV128Splat(shapeI64x2),
  2086  			)
  2087  		case wasm.OpcodeVecF32x4Splat:
  2088  			c.emit(
  2089  				newOperationV128Splat(shapeF32x4),
  2090  			)
  2091  		case wasm.OpcodeVecF64x2Splat:
  2092  			c.emit(
  2093  				newOperationV128Splat(shapeF64x2),
  2094  			)
  2095  		case wasm.OpcodeVecI8x16Swizzle:
  2096  			c.emit(
  2097  				newOperationV128Swizzle(),
  2098  			)
  2099  		case wasm.OpcodeVecV128i8x16Shuffle:
  2100  			c.pc++
  2101  			lanes := make([]uint64, 16)
  2102  			for i := uint64(0); i < 16; i++ {
  2103  				lanes[i] = uint64(c.body[c.pc+i])
  2104  			}
  2105  			op := newOperationV128Shuffle(lanes)
  2106  			c.emit(op)
  2107  			c.pc += 15
  2108  		case wasm.OpcodeVecV128AnyTrue:
  2109  			c.emit(
  2110  				newOperationV128AnyTrue(),
  2111  			)
  2112  		case wasm.OpcodeVecI8x16AllTrue:
  2113  			c.emit(
  2114  				newOperationV128AllTrue(shapeI8x16),
  2115  			)
  2116  		case wasm.OpcodeVecI16x8AllTrue:
  2117  			c.emit(
  2118  				newOperationV128AllTrue(shapeI16x8),
  2119  			)
  2120  		case wasm.OpcodeVecI32x4AllTrue:
  2121  			c.emit(
  2122  				newOperationV128AllTrue(shapeI32x4),
  2123  			)
  2124  		case wasm.OpcodeVecI64x2AllTrue:
  2125  			c.emit(
  2126  				newOperationV128AllTrue(shapeI64x2),
  2127  			)
  2128  		case wasm.OpcodeVecI8x16BitMask:
  2129  			c.emit(
  2130  				newOperationV128BitMask(shapeI8x16),
  2131  			)
  2132  		case wasm.OpcodeVecI16x8BitMask:
  2133  			c.emit(
  2134  				newOperationV128BitMask(shapeI16x8),
  2135  			)
  2136  		case wasm.OpcodeVecI32x4BitMask:
  2137  			c.emit(
  2138  				newOperationV128BitMask(shapeI32x4),
  2139  			)
  2140  		case wasm.OpcodeVecI64x2BitMask:
  2141  			c.emit(
  2142  				newOperationV128BitMask(shapeI64x2),
  2143  			)
  2144  		case wasm.OpcodeVecV128And:
  2145  			c.emit(
  2146  				newOperationV128And(),
  2147  			)
  2148  		case wasm.OpcodeVecV128Not:
  2149  			c.emit(
  2150  				newOperationV128Not(),
  2151  			)
  2152  		case wasm.OpcodeVecV128Or:
  2153  			c.emit(
  2154  				newOperationV128Or(),
  2155  			)
  2156  		case wasm.OpcodeVecV128Xor:
  2157  			c.emit(
  2158  				newOperationV128Xor(),
  2159  			)
  2160  		case wasm.OpcodeVecV128Bitselect:
  2161  			c.emit(
  2162  				newOperationV128Bitselect(),
  2163  			)
  2164  		case wasm.OpcodeVecV128AndNot:
  2165  			c.emit(
  2166  				newOperationV128AndNot(),
  2167  			)
  2168  		case wasm.OpcodeVecI8x16Shl:
  2169  			c.emit(
  2170  				newOperationV128Shl(shapeI8x16),
  2171  			)
  2172  		case wasm.OpcodeVecI8x16ShrS:
  2173  			c.emit(
  2174  				newOperationV128Shr(shapeI8x16, true),
  2175  			)
  2176  		case wasm.OpcodeVecI8x16ShrU:
  2177  			c.emit(
  2178  				newOperationV128Shr(shapeI8x16, false),
  2179  			)
  2180  		case wasm.OpcodeVecI16x8Shl:
  2181  			c.emit(
  2182  				newOperationV128Shl(shapeI16x8),
  2183  			)
  2184  		case wasm.OpcodeVecI16x8ShrS:
  2185  			c.emit(
  2186  				newOperationV128Shr(shapeI16x8, true),
  2187  			)
  2188  		case wasm.OpcodeVecI16x8ShrU:
  2189  			c.emit(
  2190  				newOperationV128Shr(shapeI16x8, false),
  2191  			)
  2192  		case wasm.OpcodeVecI32x4Shl:
  2193  			c.emit(
  2194  				newOperationV128Shl(shapeI32x4),
  2195  			)
  2196  		case wasm.OpcodeVecI32x4ShrS:
  2197  			c.emit(
  2198  				newOperationV128Shr(shapeI32x4, true),
  2199  			)
  2200  		case wasm.OpcodeVecI32x4ShrU:
  2201  			c.emit(
  2202  				newOperationV128Shr(shapeI32x4, false),
  2203  			)
  2204  		case wasm.OpcodeVecI64x2Shl:
  2205  			c.emit(
  2206  				newOperationV128Shl(shapeI64x2),
  2207  			)
  2208  		case wasm.OpcodeVecI64x2ShrS:
  2209  			c.emit(
  2210  				newOperationV128Shr(shapeI64x2, true),
  2211  			)
  2212  		case wasm.OpcodeVecI64x2ShrU:
  2213  			c.emit(
  2214  				newOperationV128Shr(shapeI64x2, false),
  2215  			)
  2216  		case wasm.OpcodeVecI8x16Eq:
  2217  			c.emit(
  2218  				newOperationV128Cmp(v128CmpTypeI8x16Eq),
  2219  			)
  2220  		case wasm.OpcodeVecI8x16Ne:
  2221  			c.emit(
  2222  				newOperationV128Cmp(v128CmpTypeI8x16Ne),
  2223  			)
  2224  		case wasm.OpcodeVecI8x16LtS:
  2225  			c.emit(
  2226  				newOperationV128Cmp(v128CmpTypeI8x16LtS),
  2227  			)
  2228  		case wasm.OpcodeVecI8x16LtU:
  2229  			c.emit(
  2230  				newOperationV128Cmp(v128CmpTypeI8x16LtU),
  2231  			)
  2232  		case wasm.OpcodeVecI8x16GtS:
  2233  			c.emit(
  2234  				newOperationV128Cmp(v128CmpTypeI8x16GtS),
  2235  			)
  2236  		case wasm.OpcodeVecI8x16GtU:
  2237  			c.emit(
  2238  				newOperationV128Cmp(v128CmpTypeI8x16GtU),
  2239  			)
  2240  		case wasm.OpcodeVecI8x16LeS:
  2241  			c.emit(
  2242  				newOperationV128Cmp(v128CmpTypeI8x16LeS),
  2243  			)
  2244  		case wasm.OpcodeVecI8x16LeU:
  2245  			c.emit(
  2246  				newOperationV128Cmp(v128CmpTypeI8x16LeU),
  2247  			)
  2248  		case wasm.OpcodeVecI8x16GeS:
  2249  			c.emit(
  2250  				newOperationV128Cmp(v128CmpTypeI8x16GeS),
  2251  			)
  2252  		case wasm.OpcodeVecI8x16GeU:
  2253  			c.emit(
  2254  				newOperationV128Cmp(v128CmpTypeI8x16GeU),
  2255  			)
  2256  		case wasm.OpcodeVecI16x8Eq:
  2257  			c.emit(
  2258  				newOperationV128Cmp(v128CmpTypeI16x8Eq),
  2259  			)
  2260  		case wasm.OpcodeVecI16x8Ne:
  2261  			c.emit(
  2262  				newOperationV128Cmp(v128CmpTypeI16x8Ne),
  2263  			)
  2264  		case wasm.OpcodeVecI16x8LtS:
  2265  			c.emit(
  2266  				newOperationV128Cmp(v128CmpTypeI16x8LtS),
  2267  			)
  2268  		case wasm.OpcodeVecI16x8LtU:
  2269  			c.emit(
  2270  				newOperationV128Cmp(v128CmpTypeI16x8LtU),
  2271  			)
  2272  		case wasm.OpcodeVecI16x8GtS:
  2273  			c.emit(
  2274  				newOperationV128Cmp(v128CmpTypeI16x8GtS),
  2275  			)
  2276  		case wasm.OpcodeVecI16x8GtU:
  2277  			c.emit(
  2278  				newOperationV128Cmp(v128CmpTypeI16x8GtU),
  2279  			)
  2280  		case wasm.OpcodeVecI16x8LeS:
  2281  			c.emit(
  2282  				newOperationV128Cmp(v128CmpTypeI16x8LeS),
  2283  			)
  2284  		case wasm.OpcodeVecI16x8LeU:
  2285  			c.emit(
  2286  				newOperationV128Cmp(v128CmpTypeI16x8LeU),
  2287  			)
  2288  		case wasm.OpcodeVecI16x8GeS:
  2289  			c.emit(
  2290  				newOperationV128Cmp(v128CmpTypeI16x8GeS),
  2291  			)
  2292  		case wasm.OpcodeVecI16x8GeU:
  2293  			c.emit(
  2294  				newOperationV128Cmp(v128CmpTypeI16x8GeU),
  2295  			)
  2296  		case wasm.OpcodeVecI32x4Eq:
  2297  			c.emit(
  2298  				newOperationV128Cmp(v128CmpTypeI32x4Eq),
  2299  			)
  2300  		case wasm.OpcodeVecI32x4Ne:
  2301  			c.emit(
  2302  				newOperationV128Cmp(v128CmpTypeI32x4Ne),
  2303  			)
  2304  		case wasm.OpcodeVecI32x4LtS:
  2305  			c.emit(
  2306  				newOperationV128Cmp(v128CmpTypeI32x4LtS),
  2307  			)
  2308  		case wasm.OpcodeVecI32x4LtU:
  2309  			c.emit(
  2310  				newOperationV128Cmp(v128CmpTypeI32x4LtU),
  2311  			)
  2312  		case wasm.OpcodeVecI32x4GtS:
  2313  			c.emit(
  2314  				newOperationV128Cmp(v128CmpTypeI32x4GtS),
  2315  			)
  2316  		case wasm.OpcodeVecI32x4GtU:
  2317  			c.emit(
  2318  				newOperationV128Cmp(v128CmpTypeI32x4GtU),
  2319  			)
  2320  		case wasm.OpcodeVecI32x4LeS:
  2321  			c.emit(
  2322  				newOperationV128Cmp(v128CmpTypeI32x4LeS),
  2323  			)
  2324  		case wasm.OpcodeVecI32x4LeU:
  2325  			c.emit(
  2326  				newOperationV128Cmp(v128CmpTypeI32x4LeU),
  2327  			)
  2328  		case wasm.OpcodeVecI32x4GeS:
  2329  			c.emit(
  2330  				newOperationV128Cmp(v128CmpTypeI32x4GeS),
  2331  			)
  2332  		case wasm.OpcodeVecI32x4GeU:
  2333  			c.emit(
  2334  				newOperationV128Cmp(v128CmpTypeI32x4GeU),
  2335  			)
  2336  		case wasm.OpcodeVecI64x2Eq:
  2337  			c.emit(
  2338  				newOperationV128Cmp(v128CmpTypeI64x2Eq),
  2339  			)
  2340  		case wasm.OpcodeVecI64x2Ne:
  2341  			c.emit(
  2342  				newOperationV128Cmp(v128CmpTypeI64x2Ne),
  2343  			)
  2344  		case wasm.OpcodeVecI64x2LtS:
  2345  			c.emit(
  2346  				newOperationV128Cmp(v128CmpTypeI64x2LtS),
  2347  			)
  2348  		case wasm.OpcodeVecI64x2GtS:
  2349  			c.emit(
  2350  				newOperationV128Cmp(v128CmpTypeI64x2GtS),
  2351  			)
  2352  		case wasm.OpcodeVecI64x2LeS:
  2353  			c.emit(
  2354  				newOperationV128Cmp(v128CmpTypeI64x2LeS),
  2355  			)
  2356  		case wasm.OpcodeVecI64x2GeS:
  2357  			c.emit(
  2358  				newOperationV128Cmp(v128CmpTypeI64x2GeS),
  2359  			)
  2360  		case wasm.OpcodeVecF32x4Eq:
  2361  			c.emit(
  2362  				newOperationV128Cmp(v128CmpTypeF32x4Eq),
  2363  			)
  2364  		case wasm.OpcodeVecF32x4Ne:
  2365  			c.emit(
  2366  				newOperationV128Cmp(v128CmpTypeF32x4Ne),
  2367  			)
  2368  		case wasm.OpcodeVecF32x4Lt:
  2369  			c.emit(
  2370  				newOperationV128Cmp(v128CmpTypeF32x4Lt),
  2371  			)
  2372  		case wasm.OpcodeVecF32x4Gt:
  2373  			c.emit(
  2374  				newOperationV128Cmp(v128CmpTypeF32x4Gt),
  2375  			)
  2376  		case wasm.OpcodeVecF32x4Le:
  2377  			c.emit(
  2378  				newOperationV128Cmp(v128CmpTypeF32x4Le),
  2379  			)
  2380  		case wasm.OpcodeVecF32x4Ge:
  2381  			c.emit(
  2382  				newOperationV128Cmp(v128CmpTypeF32x4Ge),
  2383  			)
  2384  		case wasm.OpcodeVecF64x2Eq:
  2385  			c.emit(
  2386  				newOperationV128Cmp(v128CmpTypeF64x2Eq),
  2387  			)
  2388  		case wasm.OpcodeVecF64x2Ne:
  2389  			c.emit(
  2390  				newOperationV128Cmp(v128CmpTypeF64x2Ne),
  2391  			)
  2392  		case wasm.OpcodeVecF64x2Lt:
  2393  			c.emit(
  2394  				newOperationV128Cmp(v128CmpTypeF64x2Lt),
  2395  			)
  2396  		case wasm.OpcodeVecF64x2Gt:
  2397  			c.emit(
  2398  				newOperationV128Cmp(v128CmpTypeF64x2Gt),
  2399  			)
  2400  		case wasm.OpcodeVecF64x2Le:
  2401  			c.emit(
  2402  				newOperationV128Cmp(v128CmpTypeF64x2Le),
  2403  			)
  2404  		case wasm.OpcodeVecF64x2Ge:
  2405  			c.emit(
  2406  				newOperationV128Cmp(v128CmpTypeF64x2Ge),
  2407  			)
  2408  		case wasm.OpcodeVecI8x16Neg:
  2409  			c.emit(
  2410  				newOperationV128Neg(shapeI8x16),
  2411  			)
  2412  		case wasm.OpcodeVecI16x8Neg:
  2413  			c.emit(
  2414  				newOperationV128Neg(shapeI16x8),
  2415  			)
  2416  		case wasm.OpcodeVecI32x4Neg:
  2417  			c.emit(
  2418  				newOperationV128Neg(shapeI32x4),
  2419  			)
  2420  		case wasm.OpcodeVecI64x2Neg:
  2421  			c.emit(
  2422  				newOperationV128Neg(shapeI64x2),
  2423  			)
  2424  		case wasm.OpcodeVecF32x4Neg:
  2425  			c.emit(
  2426  				newOperationV128Neg(shapeF32x4),
  2427  			)
  2428  		case wasm.OpcodeVecF64x2Neg:
  2429  			c.emit(
  2430  				newOperationV128Neg(shapeF64x2),
  2431  			)
  2432  		case wasm.OpcodeVecI8x16Add:
  2433  			c.emit(
  2434  				newOperationV128Add(shapeI8x16),
  2435  			)
  2436  		case wasm.OpcodeVecI16x8Add:
  2437  			c.emit(
  2438  				newOperationV128Add(shapeI16x8),
  2439  			)
  2440  		case wasm.OpcodeVecI32x4Add:
  2441  			c.emit(
  2442  				newOperationV128Add(shapeI32x4),
  2443  			)
  2444  		case wasm.OpcodeVecI64x2Add:
  2445  			c.emit(
  2446  				newOperationV128Add(shapeI64x2),
  2447  			)
  2448  		case wasm.OpcodeVecF32x4Add:
  2449  			c.emit(
  2450  				newOperationV128Add(shapeF32x4),
  2451  			)
  2452  		case wasm.OpcodeVecF64x2Add:
  2453  			c.emit(
  2454  				newOperationV128Add(shapeF64x2),
  2455  			)
  2456  		case wasm.OpcodeVecI8x16Sub:
  2457  			c.emit(
  2458  				newOperationV128Sub(shapeI8x16),
  2459  			)
  2460  		case wasm.OpcodeVecI16x8Sub:
  2461  			c.emit(
  2462  				newOperationV128Sub(shapeI16x8),
  2463  			)
  2464  		case wasm.OpcodeVecI32x4Sub:
  2465  			c.emit(
  2466  				newOperationV128Sub(shapeI32x4),
  2467  			)
  2468  		case wasm.OpcodeVecI64x2Sub:
  2469  			c.emit(
  2470  				newOperationV128Sub(shapeI64x2),
  2471  			)
  2472  		case wasm.OpcodeVecF32x4Sub:
  2473  			c.emit(
  2474  				newOperationV128Sub(shapeF32x4),
  2475  			)
  2476  		case wasm.OpcodeVecF64x2Sub:
  2477  			c.emit(
  2478  				newOperationV128Sub(shapeF64x2),
  2479  			)
  2480  		case wasm.OpcodeVecI8x16AddSatS:
  2481  			c.emit(
  2482  				newOperationV128AddSat(shapeI8x16, true),
  2483  			)
  2484  		case wasm.OpcodeVecI8x16AddSatU:
  2485  			c.emit(
  2486  				newOperationV128AddSat(shapeI8x16, false),
  2487  			)
  2488  		case wasm.OpcodeVecI16x8AddSatS:
  2489  			c.emit(
  2490  				newOperationV128AddSat(shapeI16x8, true),
  2491  			)
  2492  		case wasm.OpcodeVecI16x8AddSatU:
  2493  			c.emit(
  2494  				newOperationV128AddSat(shapeI16x8, false),
  2495  			)
  2496  		case wasm.OpcodeVecI8x16SubSatS:
  2497  			c.emit(
  2498  				newOperationV128SubSat(shapeI8x16, true),
  2499  			)
  2500  		case wasm.OpcodeVecI8x16SubSatU:
  2501  			c.emit(
  2502  				newOperationV128SubSat(shapeI8x16, false),
  2503  			)
  2504  		case wasm.OpcodeVecI16x8SubSatS:
  2505  			c.emit(
  2506  				newOperationV128SubSat(shapeI16x8, true),
  2507  			)
  2508  		case wasm.OpcodeVecI16x8SubSatU:
  2509  			c.emit(
  2510  				newOperationV128SubSat(shapeI16x8, false),
  2511  			)
  2512  		case wasm.OpcodeVecI16x8Mul:
  2513  			c.emit(
  2514  				newOperationV128Mul(shapeI16x8),
  2515  			)
  2516  		case wasm.OpcodeVecI32x4Mul:
  2517  			c.emit(
  2518  				newOperationV128Mul(shapeI32x4),
  2519  			)
  2520  		case wasm.OpcodeVecI64x2Mul:
  2521  			c.emit(
  2522  				newOperationV128Mul(shapeI64x2),
  2523  			)
  2524  		case wasm.OpcodeVecF32x4Mul:
  2525  			c.emit(
  2526  				newOperationV128Mul(shapeF32x4),
  2527  			)
  2528  		case wasm.OpcodeVecF64x2Mul:
  2529  			c.emit(
  2530  				newOperationV128Mul(shapeF64x2),
  2531  			)
  2532  		case wasm.OpcodeVecF32x4Sqrt:
  2533  			c.emit(
  2534  				newOperationV128Sqrt(shapeF32x4),
  2535  			)
  2536  		case wasm.OpcodeVecF64x2Sqrt:
  2537  			c.emit(
  2538  				newOperationV128Sqrt(shapeF64x2),
  2539  			)
  2540  		case wasm.OpcodeVecF32x4Div:
  2541  			c.emit(
  2542  				newOperationV128Div(shapeF32x4),
  2543  			)
  2544  		case wasm.OpcodeVecF64x2Div:
  2545  			c.emit(
  2546  				newOperationV128Div(shapeF64x2),
  2547  			)
  2548  		case wasm.OpcodeVecI8x16Abs:
  2549  			c.emit(
  2550  				newOperationV128Abs(shapeI8x16),
  2551  			)
  2552  		case wasm.OpcodeVecI8x16Popcnt:
  2553  			c.emit(
  2554  				newOperationV128Popcnt(shapeI8x16),
  2555  			)
  2556  		case wasm.OpcodeVecI16x8Abs:
  2557  			c.emit(
  2558  				newOperationV128Abs(shapeI16x8),
  2559  			)
  2560  		case wasm.OpcodeVecI32x4Abs:
  2561  			c.emit(
  2562  				newOperationV128Abs(shapeI32x4),
  2563  			)
  2564  		case wasm.OpcodeVecI64x2Abs:
  2565  			c.emit(
  2566  				newOperationV128Abs(shapeI64x2),
  2567  			)
  2568  		case wasm.OpcodeVecF32x4Abs:
  2569  			c.emit(
  2570  				newOperationV128Abs(shapeF32x4),
  2571  			)
  2572  		case wasm.OpcodeVecF64x2Abs:
  2573  			c.emit(
  2574  				newOperationV128Abs(shapeF64x2),
  2575  			)
  2576  		case wasm.OpcodeVecI8x16MinS:
  2577  			c.emit(
  2578  				newOperationV128Min(shapeI8x16, true),
  2579  			)
  2580  		case wasm.OpcodeVecI8x16MinU:
  2581  			c.emit(
  2582  				newOperationV128Min(shapeI8x16, false),
  2583  			)
  2584  		case wasm.OpcodeVecI8x16MaxS:
  2585  			c.emit(
  2586  				newOperationV128Max(shapeI8x16, true),
  2587  			)
  2588  		case wasm.OpcodeVecI8x16MaxU:
  2589  			c.emit(
  2590  				newOperationV128Max(shapeI8x16, false),
  2591  			)
  2592  		case wasm.OpcodeVecI8x16AvgrU:
  2593  			c.emit(
  2594  				newOperationV128AvgrU(shapeI8x16),
  2595  			)
  2596  		case wasm.OpcodeVecI16x8MinS:
  2597  			c.emit(
  2598  				newOperationV128Min(shapeI16x8, true),
  2599  			)
  2600  		case wasm.OpcodeVecI16x8MinU:
  2601  			c.emit(
  2602  				newOperationV128Min(shapeI16x8, false),
  2603  			)
  2604  		case wasm.OpcodeVecI16x8MaxS:
  2605  			c.emit(
  2606  				newOperationV128Max(shapeI16x8, true),
  2607  			)
  2608  		case wasm.OpcodeVecI16x8MaxU:
  2609  			c.emit(
  2610  				newOperationV128Max(shapeI16x8, false),
  2611  			)
  2612  		case wasm.OpcodeVecI16x8AvgrU:
  2613  			c.emit(
  2614  				newOperationV128AvgrU(shapeI16x8),
  2615  			)
  2616  		case wasm.OpcodeVecI32x4MinS:
  2617  			c.emit(
  2618  				newOperationV128Min(shapeI32x4, true),
  2619  			)
  2620  		case wasm.OpcodeVecI32x4MinU:
  2621  			c.emit(
  2622  				newOperationV128Min(shapeI32x4, false),
  2623  			)
  2624  		case wasm.OpcodeVecI32x4MaxS:
  2625  			c.emit(
  2626  				newOperationV128Max(shapeI32x4, true),
  2627  			)
  2628  		case wasm.OpcodeVecI32x4MaxU:
  2629  			c.emit(
  2630  				newOperationV128Max(shapeI32x4, false),
  2631  			)
  2632  		case wasm.OpcodeVecF32x4Min:
  2633  			c.emit(
  2634  				newOperationV128Min(shapeF32x4, false),
  2635  			)
  2636  		case wasm.OpcodeVecF32x4Max:
  2637  			c.emit(
  2638  				newOperationV128Max(shapeF32x4, false),
  2639  			)
  2640  		case wasm.OpcodeVecF64x2Min:
  2641  			c.emit(
  2642  				newOperationV128Min(shapeF64x2, false),
  2643  			)
  2644  		case wasm.OpcodeVecF64x2Max:
  2645  			c.emit(
  2646  				newOperationV128Max(shapeF64x2, false),
  2647  			)
  2648  		case wasm.OpcodeVecF32x4Pmin:
  2649  			c.emit(
  2650  				newOperationV128Pmin(shapeF32x4),
  2651  			)
  2652  		case wasm.OpcodeVecF32x4Pmax:
  2653  			c.emit(
  2654  				newOperationV128Pmax(shapeF32x4),
  2655  			)
  2656  		case wasm.OpcodeVecF64x2Pmin:
  2657  			c.emit(
  2658  				newOperationV128Pmin(shapeF64x2),
  2659  			)
  2660  		case wasm.OpcodeVecF64x2Pmax:
  2661  			c.emit(
  2662  				newOperationV128Pmax(shapeF64x2),
  2663  			)
  2664  		case wasm.OpcodeVecF32x4Ceil:
  2665  			c.emit(
  2666  				newOperationV128Ceil(shapeF32x4),
  2667  			)
  2668  		case wasm.OpcodeVecF32x4Floor:
  2669  			c.emit(
  2670  				newOperationV128Floor(shapeF32x4),
  2671  			)
  2672  		case wasm.OpcodeVecF32x4Trunc:
  2673  			c.emit(
  2674  				newOperationV128Trunc(shapeF32x4),
  2675  			)
  2676  		case wasm.OpcodeVecF32x4Nearest:
  2677  			c.emit(
  2678  				newOperationV128Nearest(shapeF32x4),
  2679  			)
  2680  		case wasm.OpcodeVecF64x2Ceil:
  2681  			c.emit(
  2682  				newOperationV128Ceil(shapeF64x2),
  2683  			)
  2684  		case wasm.OpcodeVecF64x2Floor:
  2685  			c.emit(
  2686  				newOperationV128Floor(shapeF64x2),
  2687  			)
  2688  		case wasm.OpcodeVecF64x2Trunc:
  2689  			c.emit(
  2690  				newOperationV128Trunc(shapeF64x2),
  2691  			)
  2692  		case wasm.OpcodeVecF64x2Nearest:
  2693  			c.emit(
  2694  				newOperationV128Nearest(shapeF64x2),
  2695  			)
  2696  		case wasm.OpcodeVecI16x8ExtendLowI8x16S:
  2697  			c.emit(
  2698  				newOperationV128Extend(shapeI8x16, true, true),
  2699  			)
  2700  		case wasm.OpcodeVecI16x8ExtendHighI8x16S:
  2701  			c.emit(
  2702  				newOperationV128Extend(shapeI8x16, true, false),
  2703  			)
  2704  		case wasm.OpcodeVecI16x8ExtendLowI8x16U:
  2705  			c.emit(
  2706  				newOperationV128Extend(shapeI8x16, false, true),
  2707  			)
  2708  		case wasm.OpcodeVecI16x8ExtendHighI8x16U:
  2709  			c.emit(
  2710  				newOperationV128Extend(shapeI8x16, false, false),
  2711  			)
  2712  		case wasm.OpcodeVecI32x4ExtendLowI16x8S:
  2713  			c.emit(
  2714  				newOperationV128Extend(shapeI16x8, true, true),
  2715  			)
  2716  		case wasm.OpcodeVecI32x4ExtendHighI16x8S:
  2717  			c.emit(
  2718  				newOperationV128Extend(shapeI16x8, true, false),
  2719  			)
  2720  		case wasm.OpcodeVecI32x4ExtendLowI16x8U:
  2721  			c.emit(
  2722  				newOperationV128Extend(shapeI16x8, false, true),
  2723  			)
  2724  		case wasm.OpcodeVecI32x4ExtendHighI16x8U:
  2725  			c.emit(
  2726  				newOperationV128Extend(shapeI16x8, false, false),
  2727  			)
  2728  		case wasm.OpcodeVecI64x2ExtendLowI32x4S:
  2729  			c.emit(
  2730  				newOperationV128Extend(shapeI32x4, true, true),
  2731  			)
  2732  		case wasm.OpcodeVecI64x2ExtendHighI32x4S:
  2733  			c.emit(
  2734  				newOperationV128Extend(shapeI32x4, true, false),
  2735  			)
  2736  		case wasm.OpcodeVecI64x2ExtendLowI32x4U:
  2737  			c.emit(
  2738  				newOperationV128Extend(shapeI32x4, false, true),
  2739  			)
  2740  		case wasm.OpcodeVecI64x2ExtendHighI32x4U:
  2741  			c.emit(
  2742  				newOperationV128Extend(shapeI32x4, false, false),
  2743  			)
  2744  		case wasm.OpcodeVecI16x8Q15mulrSatS:
  2745  			c.emit(
  2746  				newOperationV128Q15mulrSatS(),
  2747  			)
  2748  		case wasm.OpcodeVecI16x8ExtMulLowI8x16S:
  2749  			c.emit(
  2750  				newOperationV128ExtMul(shapeI8x16, true, true),
  2751  			)
  2752  		case wasm.OpcodeVecI16x8ExtMulHighI8x16S:
  2753  			c.emit(
  2754  				newOperationV128ExtMul(shapeI8x16, true, false),
  2755  			)
  2756  		case wasm.OpcodeVecI16x8ExtMulLowI8x16U:
  2757  			c.emit(
  2758  				newOperationV128ExtMul(shapeI8x16, false, true),
  2759  			)
  2760  		case wasm.OpcodeVecI16x8ExtMulHighI8x16U:
  2761  			c.emit(
  2762  				newOperationV128ExtMul(shapeI8x16, false, false),
  2763  			)
  2764  		case wasm.OpcodeVecI32x4ExtMulLowI16x8S:
  2765  			c.emit(
  2766  				newOperationV128ExtMul(shapeI16x8, true, true),
  2767  			)
  2768  		case wasm.OpcodeVecI32x4ExtMulHighI16x8S:
  2769  			c.emit(
  2770  				newOperationV128ExtMul(shapeI16x8, true, false),
  2771  			)
  2772  		case wasm.OpcodeVecI32x4ExtMulLowI16x8U:
  2773  			c.emit(
  2774  				newOperationV128ExtMul(shapeI16x8, false, true),
  2775  			)
  2776  		case wasm.OpcodeVecI32x4ExtMulHighI16x8U:
  2777  			c.emit(
  2778  				newOperationV128ExtMul(shapeI16x8, false, false),
  2779  			)
  2780  		case wasm.OpcodeVecI64x2ExtMulLowI32x4S:
  2781  			c.emit(
  2782  				newOperationV128ExtMul(shapeI32x4, true, true),
  2783  			)
  2784  		case wasm.OpcodeVecI64x2ExtMulHighI32x4S:
  2785  			c.emit(
  2786  				newOperationV128ExtMul(shapeI32x4, true, false),
  2787  			)
  2788  		case wasm.OpcodeVecI64x2ExtMulLowI32x4U:
  2789  			c.emit(
  2790  				newOperationV128ExtMul(shapeI32x4, false, true),
  2791  			)
  2792  		case wasm.OpcodeVecI64x2ExtMulHighI32x4U:
  2793  			c.emit(
  2794  				newOperationV128ExtMul(shapeI32x4, false, false),
  2795  			)
  2796  		case wasm.OpcodeVecI16x8ExtaddPairwiseI8x16S:
  2797  			c.emit(
  2798  				newOperationV128ExtAddPairwise(shapeI8x16, true),
  2799  			)
  2800  		case wasm.OpcodeVecI16x8ExtaddPairwiseI8x16U:
  2801  			c.emit(
  2802  				newOperationV128ExtAddPairwise(shapeI8x16, false),
  2803  			)
  2804  		case wasm.OpcodeVecI32x4ExtaddPairwiseI16x8S:
  2805  			c.emit(
  2806  				newOperationV128ExtAddPairwise(shapeI16x8, true),
  2807  			)
  2808  		case wasm.OpcodeVecI32x4ExtaddPairwiseI16x8U:
  2809  			c.emit(
  2810  				newOperationV128ExtAddPairwise(shapeI16x8, false),
  2811  			)
  2812  		case wasm.OpcodeVecF64x2PromoteLowF32x4Zero:
  2813  			c.emit(
  2814  				newOperationV128FloatPromote(),
  2815  			)
  2816  		case wasm.OpcodeVecF32x4DemoteF64x2Zero:
  2817  			c.emit(
  2818  				newOperationV128FloatDemote(),
  2819  			)
  2820  		case wasm.OpcodeVecF32x4ConvertI32x4S:
  2821  			c.emit(
  2822  				newOperationV128FConvertFromI(shapeF32x4, true),
  2823  			)
  2824  		case wasm.OpcodeVecF32x4ConvertI32x4U:
  2825  			c.emit(
  2826  				newOperationV128FConvertFromI(shapeF32x4, false),
  2827  			)
  2828  		case wasm.OpcodeVecF64x2ConvertLowI32x4S:
  2829  			c.emit(
  2830  				newOperationV128FConvertFromI(shapeF64x2, true),
  2831  			)
  2832  		case wasm.OpcodeVecF64x2ConvertLowI32x4U:
  2833  			c.emit(
  2834  				newOperationV128FConvertFromI(shapeF64x2, false),
  2835  			)
  2836  		case wasm.OpcodeVecI32x4DotI16x8S:
  2837  			c.emit(
  2838  				newOperationV128Dot(),
  2839  			)
  2840  		case wasm.OpcodeVecI8x16NarrowI16x8S:
  2841  			c.emit(
  2842  				newOperationV128Narrow(shapeI16x8, true),
  2843  			)
  2844  		case wasm.OpcodeVecI8x16NarrowI16x8U:
  2845  			c.emit(
  2846  				newOperationV128Narrow(shapeI16x8, false),
  2847  			)
  2848  		case wasm.OpcodeVecI16x8NarrowI32x4S:
  2849  			c.emit(
  2850  				newOperationV128Narrow(shapeI32x4, true),
  2851  			)
  2852  		case wasm.OpcodeVecI16x8NarrowI32x4U:
  2853  			c.emit(
  2854  				newOperationV128Narrow(shapeI32x4, false),
  2855  			)
  2856  		case wasm.OpcodeVecI32x4TruncSatF32x4S:
  2857  			c.emit(
  2858  				newOperationV128ITruncSatFromF(shapeF32x4, true),
  2859  			)
  2860  		case wasm.OpcodeVecI32x4TruncSatF32x4U:
  2861  			c.emit(
  2862  				newOperationV128ITruncSatFromF(shapeF32x4, false),
  2863  			)
  2864  		case wasm.OpcodeVecI32x4TruncSatF64x2SZero:
  2865  			c.emit(
  2866  				newOperationV128ITruncSatFromF(shapeF64x2, true),
  2867  			)
  2868  		case wasm.OpcodeVecI32x4TruncSatF64x2UZero:
  2869  			c.emit(
  2870  				newOperationV128ITruncSatFromF(shapeF64x2, false),
  2871  			)
  2872  		default:
  2873  			return fmt.Errorf("unsupported vector instruction in interpreterir: %s", wasm.VectorInstructionName(vecOp))
  2874  		}
  2875  	case wasm.OpcodeAtomicPrefix:
  2876  		c.pc++
  2877  		atomicOp := c.body[c.pc]
  2878  		switch atomicOp {
  2879  		case wasm.OpcodeAtomicMemoryWait32:
  2880  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicMemoryWait32Name)
  2881  			if err != nil {
  2882  				return err
  2883  			}
  2884  			c.emit(
  2885  				newOperationAtomicMemoryWait(unsignedTypeI32, imm),
  2886  			)
  2887  		case wasm.OpcodeAtomicMemoryWait64:
  2888  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicMemoryWait64Name)
  2889  			if err != nil {
  2890  				return err
  2891  			}
  2892  			c.emit(
  2893  				newOperationAtomicMemoryWait(unsignedTypeI64, imm),
  2894  			)
  2895  		case wasm.OpcodeAtomicMemoryNotify:
  2896  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicMemoryNotifyName)
  2897  			if err != nil {
  2898  				return err
  2899  			}
  2900  			c.emit(
  2901  				newOperationAtomicMemoryNotify(imm),
  2902  			)
  2903  		case wasm.OpcodeAtomicFence:
  2904  			// Skip immediate value
  2905  			c.pc++
  2906  			_ = c.body[c.pc]
  2907  			c.emit(
  2908  				newOperationAtomicFence(),
  2909  			)
  2910  		case wasm.OpcodeAtomicI32Load:
  2911  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32LoadName)
  2912  			if err != nil {
  2913  				return err
  2914  			}
  2915  			c.emit(
  2916  				newOperationAtomicLoad(unsignedTypeI32, imm),
  2917  			)
  2918  		case wasm.OpcodeAtomicI64Load:
  2919  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64LoadName)
  2920  			if err != nil {
  2921  				return err
  2922  			}
  2923  			c.emit(
  2924  				newOperationAtomicLoad(unsignedTypeI64, imm),
  2925  			)
  2926  		case wasm.OpcodeAtomicI32Load8U:
  2927  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Load8UName)
  2928  			if err != nil {
  2929  				return err
  2930  			}
  2931  			c.emit(
  2932  				newOperationAtomicLoad8(unsignedTypeI32, imm),
  2933  			)
  2934  		case wasm.OpcodeAtomicI32Load16U:
  2935  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Load16UName)
  2936  			if err != nil {
  2937  				return err
  2938  			}
  2939  			c.emit(
  2940  				newOperationAtomicLoad16(unsignedTypeI32, imm),
  2941  			)
  2942  		case wasm.OpcodeAtomicI64Load8U:
  2943  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Load8UName)
  2944  			if err != nil {
  2945  				return err
  2946  			}
  2947  			c.emit(
  2948  				newOperationAtomicLoad8(unsignedTypeI64, imm),
  2949  			)
  2950  		case wasm.OpcodeAtomicI64Load16U:
  2951  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Load16UName)
  2952  			if err != nil {
  2953  				return err
  2954  			}
  2955  			c.emit(
  2956  				newOperationAtomicLoad16(unsignedTypeI64, imm),
  2957  			)
  2958  		case wasm.OpcodeAtomicI64Load32U:
  2959  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Load32UName)
  2960  			if err != nil {
  2961  				return err
  2962  			}
  2963  			c.emit(
  2964  				newOperationAtomicLoad(unsignedTypeI32, imm),
  2965  			)
  2966  		case wasm.OpcodeAtomicI32Store:
  2967  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32StoreName)
  2968  			if err != nil {
  2969  				return err
  2970  			}
  2971  			c.emit(
  2972  				newOperationAtomicStore(unsignedTypeI32, imm),
  2973  			)
  2974  		case wasm.OpcodeAtomicI32Store8:
  2975  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Store8Name)
  2976  			if err != nil {
  2977  				return err
  2978  			}
  2979  			c.emit(
  2980  				newOperationAtomicStore8(unsignedTypeI32, imm),
  2981  			)
  2982  		case wasm.OpcodeAtomicI32Store16:
  2983  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Store16Name)
  2984  			if err != nil {
  2985  				return err
  2986  			}
  2987  			c.emit(
  2988  				newOperationAtomicStore16(unsignedTypeI32, imm),
  2989  			)
  2990  		case wasm.OpcodeAtomicI64Store:
  2991  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64StoreName)
  2992  			if err != nil {
  2993  				return err
  2994  			}
  2995  			c.emit(
  2996  				newOperationAtomicStore(unsignedTypeI64, imm),
  2997  			)
  2998  		case wasm.OpcodeAtomicI64Store8:
  2999  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Store8Name)
  3000  			if err != nil {
  3001  				return err
  3002  			}
  3003  			c.emit(
  3004  				newOperationAtomicStore8(unsignedTypeI64, imm),
  3005  			)
  3006  		case wasm.OpcodeAtomicI64Store16:
  3007  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Store16Name)
  3008  			if err != nil {
  3009  				return err
  3010  			}
  3011  			c.emit(
  3012  				newOperationAtomicStore16(unsignedTypeI64, imm),
  3013  			)
  3014  		case wasm.OpcodeAtomicI64Store32:
  3015  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Store32Name)
  3016  			if err != nil {
  3017  				return err
  3018  			}
  3019  			c.emit(
  3020  				newOperationAtomicStore(unsignedTypeI32, imm),
  3021  			)
  3022  		case wasm.OpcodeAtomicI32RmwAdd:
  3023  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32RmwAddName)
  3024  			if err != nil {
  3025  				return err
  3026  			}
  3027  			c.emit(
  3028  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpAdd),
  3029  			)
  3030  		case wasm.OpcodeAtomicI64RmwAdd:
  3031  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64RmwAddName)
  3032  			if err != nil {
  3033  				return err
  3034  			}
  3035  			c.emit(
  3036  				newOperationAtomicRMW(unsignedTypeI64, imm, atomicArithmeticOpAdd),
  3037  			)
  3038  		case wasm.OpcodeAtomicI32Rmw8AddU:
  3039  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw8AddUName)
  3040  			if err != nil {
  3041  				return err
  3042  			}
  3043  			c.emit(
  3044  				newOperationAtomicRMW8(unsignedTypeI32, imm, atomicArithmeticOpAdd),
  3045  			)
  3046  		case wasm.OpcodeAtomicI64Rmw8AddU:
  3047  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw8AddUName)
  3048  			if err != nil {
  3049  				return err
  3050  			}
  3051  			c.emit(
  3052  				newOperationAtomicRMW8(unsignedTypeI64, imm, atomicArithmeticOpAdd),
  3053  			)
  3054  		case wasm.OpcodeAtomicI32Rmw16AddU:
  3055  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw16AddUName)
  3056  			if err != nil {
  3057  				return err
  3058  			}
  3059  			c.emit(
  3060  				newOperationAtomicRMW16(unsignedTypeI32, imm, atomicArithmeticOpAdd),
  3061  			)
  3062  		case wasm.OpcodeAtomicI64Rmw16AddU:
  3063  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw16AddUName)
  3064  			if err != nil {
  3065  				return err
  3066  			}
  3067  			c.emit(
  3068  				newOperationAtomicRMW16(unsignedTypeI64, imm, atomicArithmeticOpAdd),
  3069  			)
  3070  		case wasm.OpcodeAtomicI64Rmw32AddU:
  3071  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw32AddUName)
  3072  			if err != nil {
  3073  				return err
  3074  			}
  3075  			c.emit(
  3076  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpAdd),
  3077  			)
  3078  		case wasm.OpcodeAtomicI32RmwSub:
  3079  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32RmwSubName)
  3080  			if err != nil {
  3081  				return err
  3082  			}
  3083  			c.emit(
  3084  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpSub),
  3085  			)
  3086  		case wasm.OpcodeAtomicI64RmwSub:
  3087  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64RmwSubName)
  3088  			if err != nil {
  3089  				return err
  3090  			}
  3091  			c.emit(
  3092  				newOperationAtomicRMW(unsignedTypeI64, imm, atomicArithmeticOpSub),
  3093  			)
  3094  		case wasm.OpcodeAtomicI32Rmw8SubU:
  3095  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw8SubUName)
  3096  			if err != nil {
  3097  				return err
  3098  			}
  3099  			c.emit(
  3100  				newOperationAtomicRMW8(unsignedTypeI32, imm, atomicArithmeticOpSub),
  3101  			)
  3102  		case wasm.OpcodeAtomicI64Rmw8SubU:
  3103  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw8SubUName)
  3104  			if err != nil {
  3105  				return err
  3106  			}
  3107  			c.emit(
  3108  				newOperationAtomicRMW8(unsignedTypeI64, imm, atomicArithmeticOpSub),
  3109  			)
  3110  		case wasm.OpcodeAtomicI32Rmw16SubU:
  3111  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw16SubUName)
  3112  			if err != nil {
  3113  				return err
  3114  			}
  3115  			c.emit(
  3116  				newOperationAtomicRMW16(unsignedTypeI32, imm, atomicArithmeticOpSub),
  3117  			)
  3118  		case wasm.OpcodeAtomicI64Rmw16SubU:
  3119  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw16SubUName)
  3120  			if err != nil {
  3121  				return err
  3122  			}
  3123  			c.emit(
  3124  				newOperationAtomicRMW16(unsignedTypeI64, imm, atomicArithmeticOpSub),
  3125  			)
  3126  		case wasm.OpcodeAtomicI64Rmw32SubU:
  3127  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw32SubUName)
  3128  			if err != nil {
  3129  				return err
  3130  			}
  3131  			c.emit(
  3132  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpSub),
  3133  			)
  3134  		case wasm.OpcodeAtomicI32RmwAnd:
  3135  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32RmwAndName)
  3136  			if err != nil {
  3137  				return err
  3138  			}
  3139  			c.emit(
  3140  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpAnd),
  3141  			)
  3142  		case wasm.OpcodeAtomicI64RmwAnd:
  3143  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64RmwAndName)
  3144  			if err != nil {
  3145  				return err
  3146  			}
  3147  			c.emit(
  3148  				newOperationAtomicRMW(unsignedTypeI64, imm, atomicArithmeticOpAnd),
  3149  			)
  3150  		case wasm.OpcodeAtomicI32Rmw8AndU:
  3151  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw8AndUName)
  3152  			if err != nil {
  3153  				return err
  3154  			}
  3155  			c.emit(
  3156  				newOperationAtomicRMW8(unsignedTypeI32, imm, atomicArithmeticOpAnd),
  3157  			)
  3158  		case wasm.OpcodeAtomicI64Rmw8AndU:
  3159  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw8AndUName)
  3160  			if err != nil {
  3161  				return err
  3162  			}
  3163  			c.emit(
  3164  				newOperationAtomicRMW8(unsignedTypeI64, imm, atomicArithmeticOpAnd),
  3165  			)
  3166  		case wasm.OpcodeAtomicI32Rmw16AndU:
  3167  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw16AndUName)
  3168  			if err != nil {
  3169  				return err
  3170  			}
  3171  			c.emit(
  3172  				newOperationAtomicRMW16(unsignedTypeI32, imm, atomicArithmeticOpAnd),
  3173  			)
  3174  		case wasm.OpcodeAtomicI64Rmw16AndU:
  3175  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw16AndUName)
  3176  			if err != nil {
  3177  				return err
  3178  			}
  3179  			c.emit(
  3180  				newOperationAtomicRMW16(unsignedTypeI64, imm, atomicArithmeticOpAnd),
  3181  			)
  3182  		case wasm.OpcodeAtomicI64Rmw32AndU:
  3183  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw32AndUName)
  3184  			if err != nil {
  3185  				return err
  3186  			}
  3187  			c.emit(
  3188  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpAnd),
  3189  			)
  3190  		case wasm.OpcodeAtomicI32RmwOr:
  3191  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32RmwOrName)
  3192  			if err != nil {
  3193  				return err
  3194  			}
  3195  			c.emit(
  3196  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpOr),
  3197  			)
  3198  		case wasm.OpcodeAtomicI64RmwOr:
  3199  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64RmwOrName)
  3200  			if err != nil {
  3201  				return err
  3202  			}
  3203  			c.emit(
  3204  				newOperationAtomicRMW(unsignedTypeI64, imm, atomicArithmeticOpOr),
  3205  			)
  3206  		case wasm.OpcodeAtomicI32Rmw8OrU:
  3207  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw8OrUName)
  3208  			if err != nil {
  3209  				return err
  3210  			}
  3211  			c.emit(
  3212  				newOperationAtomicRMW8(unsignedTypeI32, imm, atomicArithmeticOpOr),
  3213  			)
  3214  		case wasm.OpcodeAtomicI64Rmw8OrU:
  3215  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw8OrUName)
  3216  			if err != nil {
  3217  				return err
  3218  			}
  3219  			c.emit(
  3220  				newOperationAtomicRMW8(unsignedTypeI64, imm, atomicArithmeticOpOr),
  3221  			)
  3222  		case wasm.OpcodeAtomicI32Rmw16OrU:
  3223  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw16OrUName)
  3224  			if err != nil {
  3225  				return err
  3226  			}
  3227  			c.emit(
  3228  				newOperationAtomicRMW16(unsignedTypeI32, imm, atomicArithmeticOpOr),
  3229  			)
  3230  		case wasm.OpcodeAtomicI64Rmw16OrU:
  3231  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw16OrUName)
  3232  			if err != nil {
  3233  				return err
  3234  			}
  3235  			c.emit(
  3236  				newOperationAtomicRMW16(unsignedTypeI64, imm, atomicArithmeticOpOr),
  3237  			)
  3238  		case wasm.OpcodeAtomicI64Rmw32OrU:
  3239  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw32OrUName)
  3240  			if err != nil {
  3241  				return err
  3242  			}
  3243  			c.emit(
  3244  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpOr),
  3245  			)
  3246  		case wasm.OpcodeAtomicI32RmwXor:
  3247  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32RmwXorName)
  3248  			if err != nil {
  3249  				return err
  3250  			}
  3251  			c.emit(
  3252  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpXor),
  3253  			)
  3254  		case wasm.OpcodeAtomicI64RmwXor:
  3255  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64RmwXorName)
  3256  			if err != nil {
  3257  				return err
  3258  			}
  3259  			c.emit(
  3260  				newOperationAtomicRMW(unsignedTypeI64, imm, atomicArithmeticOpXor),
  3261  			)
  3262  		case wasm.OpcodeAtomicI32Rmw8XorU:
  3263  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw8XorUName)
  3264  			if err != nil {
  3265  				return err
  3266  			}
  3267  			c.emit(
  3268  				newOperationAtomicRMW8(unsignedTypeI32, imm, atomicArithmeticOpXor),
  3269  			)
  3270  		case wasm.OpcodeAtomicI64Rmw8XorU:
  3271  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw8XorUName)
  3272  			if err != nil {
  3273  				return err
  3274  			}
  3275  			c.emit(
  3276  				newOperationAtomicRMW8(unsignedTypeI64, imm, atomicArithmeticOpXor),
  3277  			)
  3278  		case wasm.OpcodeAtomicI32Rmw16XorU:
  3279  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw16XorUName)
  3280  			if err != nil {
  3281  				return err
  3282  			}
  3283  			c.emit(
  3284  				newOperationAtomicRMW16(unsignedTypeI32, imm, atomicArithmeticOpXor),
  3285  			)
  3286  		case wasm.OpcodeAtomicI64Rmw16XorU:
  3287  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw16XorUName)
  3288  			if err != nil {
  3289  				return err
  3290  			}
  3291  			c.emit(
  3292  				newOperationAtomicRMW16(unsignedTypeI64, imm, atomicArithmeticOpXor),
  3293  			)
  3294  		case wasm.OpcodeAtomicI64Rmw32XorU:
  3295  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw32XorUName)
  3296  			if err != nil {
  3297  				return err
  3298  			}
  3299  			c.emit(
  3300  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpXor),
  3301  			)
  3302  		case wasm.OpcodeAtomicI32RmwXchg:
  3303  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32RmwXchgName)
  3304  			if err != nil {
  3305  				return err
  3306  			}
  3307  			c.emit(
  3308  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpNop),
  3309  			)
  3310  		case wasm.OpcodeAtomicI64RmwXchg:
  3311  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64RmwXchgName)
  3312  			if err != nil {
  3313  				return err
  3314  			}
  3315  			c.emit(
  3316  				newOperationAtomicRMW(unsignedTypeI64, imm, atomicArithmeticOpNop),
  3317  			)
  3318  		case wasm.OpcodeAtomicI32Rmw8XchgU:
  3319  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw8XchgUName)
  3320  			if err != nil {
  3321  				return err
  3322  			}
  3323  			c.emit(
  3324  				newOperationAtomicRMW8(unsignedTypeI32, imm, atomicArithmeticOpNop),
  3325  			)
  3326  		case wasm.OpcodeAtomicI64Rmw8XchgU:
  3327  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw8XchgUName)
  3328  			if err != nil {
  3329  				return err
  3330  			}
  3331  			c.emit(
  3332  				newOperationAtomicRMW8(unsignedTypeI64, imm, atomicArithmeticOpNop),
  3333  			)
  3334  		case wasm.OpcodeAtomicI32Rmw16XchgU:
  3335  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw16XchgUName)
  3336  			if err != nil {
  3337  				return err
  3338  			}
  3339  			c.emit(
  3340  				newOperationAtomicRMW16(unsignedTypeI32, imm, atomicArithmeticOpNop),
  3341  			)
  3342  		case wasm.OpcodeAtomicI64Rmw16XchgU:
  3343  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw16XchgUName)
  3344  			if err != nil {
  3345  				return err
  3346  			}
  3347  			c.emit(
  3348  				newOperationAtomicRMW16(unsignedTypeI64, imm, atomicArithmeticOpNop),
  3349  			)
  3350  		case wasm.OpcodeAtomicI64Rmw32XchgU:
  3351  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw32XchgUName)
  3352  			if err != nil {
  3353  				return err
  3354  			}
  3355  			c.emit(
  3356  				newOperationAtomicRMW(unsignedTypeI32, imm, atomicArithmeticOpNop),
  3357  			)
  3358  		case wasm.OpcodeAtomicI32RmwCmpxchg:
  3359  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32RmwCmpxchgName)
  3360  			if err != nil {
  3361  				return err
  3362  			}
  3363  			c.emit(
  3364  				newOperationAtomicRMWCmpxchg(unsignedTypeI32, imm),
  3365  			)
  3366  		case wasm.OpcodeAtomicI64RmwCmpxchg:
  3367  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64RmwCmpxchgName)
  3368  			if err != nil {
  3369  				return err
  3370  			}
  3371  			c.emit(
  3372  				newOperationAtomicRMWCmpxchg(unsignedTypeI64, imm),
  3373  			)
  3374  		case wasm.OpcodeAtomicI32Rmw8CmpxchgU:
  3375  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw8CmpxchgUName)
  3376  			if err != nil {
  3377  				return err
  3378  			}
  3379  			c.emit(
  3380  				newOperationAtomicRMW8Cmpxchg(unsignedTypeI32, imm),
  3381  			)
  3382  		case wasm.OpcodeAtomicI64Rmw8CmpxchgU:
  3383  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw8CmpxchgUName)
  3384  			if err != nil {
  3385  				return err
  3386  			}
  3387  			c.emit(
  3388  				newOperationAtomicRMW8Cmpxchg(unsignedTypeI64, imm),
  3389  			)
  3390  		case wasm.OpcodeAtomicI32Rmw16CmpxchgU:
  3391  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI32Rmw16CmpxchgUName)
  3392  			if err != nil {
  3393  				return err
  3394  			}
  3395  			c.emit(
  3396  				newOperationAtomicRMW16Cmpxchg(unsignedTypeI32, imm),
  3397  			)
  3398  		case wasm.OpcodeAtomicI64Rmw16CmpxchgU:
  3399  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw16CmpxchgUName)
  3400  			if err != nil {
  3401  				return err
  3402  			}
  3403  			c.emit(
  3404  				newOperationAtomicRMW16Cmpxchg(unsignedTypeI64, imm),
  3405  			)
  3406  		case wasm.OpcodeAtomicI64Rmw32CmpxchgU:
  3407  			imm, err := c.readMemoryArg(wasm.OpcodeAtomicI64Rmw32CmpxchgUName)
  3408  			if err != nil {
  3409  				return err
  3410  			}
  3411  			c.emit(
  3412  				newOperationAtomicRMWCmpxchg(unsignedTypeI32, imm),
  3413  			)
  3414  		default:
  3415  			return fmt.Errorf("unsupported atomic instruction in interpreterir: %s", wasm.AtomicInstructionName(atomicOp))
  3416  		}
  3417  	default:
  3418  		return fmt.Errorf("unsupported instruction in interpreterir: 0x%x", op)
  3419  	}
  3420  
  3421  	// Move the program counter to point to the next instruction.
  3422  	c.pc++
  3423  	return nil
  3424  }
  3425  
  3426  func (c *compiler) nextFrameID() (id uint32) {
  3427  	id = c.currentFrameID + 1
  3428  	c.currentFrameID++
  3429  	return
  3430  }
  3431  
  3432  func (c *compiler) applyToStack(opcode wasm.Opcode) (index uint32, err error) {
  3433  	switch opcode {
  3434  	case
  3435  		// These are the opcodes that is coupled with "index" immediate
  3436  		// and it DOES affect the signature of opcode.
  3437  		wasm.OpcodeCall,
  3438  		wasm.OpcodeCallIndirect,
  3439  		wasm.OpcodeLocalGet,
  3440  		wasm.OpcodeLocalSet,
  3441  		wasm.OpcodeLocalTee,
  3442  		wasm.OpcodeGlobalGet,
  3443  		wasm.OpcodeGlobalSet:
  3444  		// Assumes that we are at the opcode now so skip it before read immediates.
  3445  		v, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  3446  		if err != nil {
  3447  			return 0, fmt.Errorf("reading immediates: %w", err)
  3448  		}
  3449  		c.pc += num
  3450  		index = v
  3451  	default:
  3452  		// Note that other opcodes are free of index
  3453  		// as it doesn't affect the signature of opt code.
  3454  		// In other words, the "index" argument of wasmOpcodeSignature
  3455  		// is ignored there.
  3456  	}
  3457  
  3458  	if c.unreachableState.on {
  3459  		return 0, nil
  3460  	}
  3461  
  3462  	// Retrieve the signature of the opcode.
  3463  	s, err := c.wasmOpcodeSignature(opcode, index)
  3464  	if err != nil {
  3465  		return 0, err
  3466  	}
  3467  
  3468  	// Manipulate the stack according to the signature.
  3469  	// Note that the following algorithm assumes that
  3470  	// the unknown type is unique in the signature,
  3471  	// and is determined by the actual type on the stack.
  3472  	// The determined type is stored in this typeParam.
  3473  	var typeParam unsignedType
  3474  	var typeParamFound bool
  3475  	for i := range s.in {
  3476  		want := s.in[len(s.in)-1-i]
  3477  		actual := c.stackPop()
  3478  		if want == unsignedTypeUnknown && typeParamFound {
  3479  			want = typeParam
  3480  		} else if want == unsignedTypeUnknown {
  3481  			want = actual
  3482  			typeParam = want
  3483  			typeParamFound = true
  3484  		}
  3485  		if want != actual {
  3486  			return 0, fmt.Errorf("input signature mismatch: want %s but have %s", want, actual)
  3487  		}
  3488  	}
  3489  
  3490  	for _, target := range s.out {
  3491  		if target == unsignedTypeUnknown && !typeParamFound {
  3492  			return 0, fmt.Errorf("cannot determine type of unknown result")
  3493  		} else if target == unsignedTypeUnknown {
  3494  			c.stackPush(typeParam)
  3495  		} else {
  3496  			c.stackPush(target)
  3497  		}
  3498  	}
  3499  
  3500  	return index, nil
  3501  }
  3502  
  3503  func (c *compiler) stackPeek() (ret unsignedType) {
  3504  	ret = c.stack[len(c.stack)-1]
  3505  	return
  3506  }
  3507  
  3508  func (c *compiler) stackPop() (ret unsignedType) {
  3509  	// No need to check stack bound
  3510  	// as we can assume that all the operations
  3511  	// are valid thanks to validateFunction
  3512  	// at module validation phase.
  3513  	ret = c.stack[len(c.stack)-1]
  3514  	c.stack = c.stack[:len(c.stack)-1]
  3515  	return
  3516  }
  3517  
  3518  func (c *compiler) stackPush(ts unsignedType) {
  3519  	c.stack = append(c.stack, ts)
  3520  }
  3521  
  3522  // emit adds the operations into the result.
  3523  func (c *compiler) emit(op unionOperation) {
  3524  	if !c.unreachableState.on {
  3525  		switch op.Kind {
  3526  		case operationKindDrop:
  3527  			// If the drop range is nil,
  3528  			// we could remove such operations.
  3529  			// That happens when drop operation is unnecessary.
  3530  			// i.e. when there's no need to adjust stack before jmp.
  3531  			if int64(op.U1) == -1 {
  3532  				return
  3533  			}
  3534  		}
  3535  		c.result.Operations = append(c.result.Operations, op)
  3536  		if c.needSourceOffset {
  3537  			c.result.IROperationSourceOffsetsInWasmBinary = append(c.result.IROperationSourceOffsetsInWasmBinary,
  3538  				c.currentOpPC+c.bodyOffsetInCodeSection)
  3539  		}
  3540  	}
  3541  }
  3542  
  3543  // Emit const expression with default values of the given type.
  3544  func (c *compiler) emitDefaultValue(t wasm.ValueType) {
  3545  	switch t {
  3546  	case wasm.ValueTypeI32:
  3547  		c.stackPush(unsignedTypeI32)
  3548  		c.emit(newOperationConstI32(0))
  3549  	case wasm.ValueTypeI64, wasm.ValueTypeExternref, wasm.ValueTypeFuncref:
  3550  		c.stackPush(unsignedTypeI64)
  3551  		c.emit(newOperationConstI64(0))
  3552  	case wasm.ValueTypeF32:
  3553  		c.stackPush(unsignedTypeF32)
  3554  		c.emit(newOperationConstF32(0))
  3555  	case wasm.ValueTypeF64:
  3556  		c.stackPush(unsignedTypeF64)
  3557  		c.emit(newOperationConstF64(0))
  3558  	case wasm.ValueTypeV128:
  3559  		c.stackPush(unsignedTypeV128)
  3560  		c.emit(newOperationV128Const(0, 0))
  3561  	}
  3562  }
  3563  
  3564  // Returns the "depth" (starting from top of the stack)
  3565  // of the n-th local.
  3566  func (c *compiler) localDepth(index wasm.Index) int {
  3567  	height := c.localIndexToStackHeightInUint64[index]
  3568  	return c.stackLenInUint64(len(c.stack)) - 1 - int(height)
  3569  }
  3570  
  3571  func (c *compiler) localType(index wasm.Index) (t wasm.ValueType) {
  3572  	if params := uint32(len(c.sig.Params)); index < params {
  3573  		t = c.sig.Params[index]
  3574  	} else {
  3575  		t = c.localTypes[index-params]
  3576  	}
  3577  	return
  3578  }
  3579  
  3580  // getFrameDropRange returns the range (starting from top of the stack) that spans across the (uint64) stack. The range is
  3581  // supposed to be dropped from the stack when the given frame exists or branch into it.
  3582  //
  3583  // * frame is the control frame which the call-site is trying to branch into or exit.
  3584  // * isEnd true if the call-site is handling wasm.OpcodeEnd.
  3585  func (c *compiler) getFrameDropRange(frame *controlFrame, isEnd bool) inclusiveRange {
  3586  	var start int
  3587  	if !isEnd && frame.kind == controlFrameKindLoop {
  3588  		// If this is not End and the call-site is trying to branch into the Loop control frame,
  3589  		// we have to Start executing from the beginning of the loop block.
  3590  		// Therefore, we have to pass the inputs to the frame.
  3591  		start = frame.blockType.ParamNumInUint64
  3592  	} else {
  3593  		start = frame.blockType.ResultNumInUint64
  3594  	}
  3595  	var end int
  3596  	if frame.kind == controlFrameKindFunction {
  3597  		// On the function return, we eliminate all the contents on the stack
  3598  		// including locals (existing below of frame.originalStackLen)
  3599  		end = c.stackLenInUint64(len(c.stack)) - 1
  3600  	} else {
  3601  		end = c.stackLenInUint64(len(c.stack)) - 1 - c.stackLenInUint64(frame.originalStackLenWithoutParam)
  3602  	}
  3603  	if start <= end {
  3604  		return inclusiveRange{Start: int32(start), End: int32(end)}
  3605  	} else {
  3606  		return nopinclusiveRange
  3607  	}
  3608  }
  3609  
  3610  func (c *compiler) stackLenInUint64(ceil int) (ret int) {
  3611  	for i := 0; i < ceil; i++ {
  3612  		if c.stack[i] == unsignedTypeV128 {
  3613  			ret += 2
  3614  		} else {
  3615  			ret++
  3616  		}
  3617  	}
  3618  	return
  3619  }
  3620  
  3621  func (c *compiler) readMemoryArg(tag string) (memoryArg, error) {
  3622  	c.result.UsesMemory = true
  3623  	alignment, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  3624  	if err != nil {
  3625  		return memoryArg{}, fmt.Errorf("reading alignment for %s: %w", tag, err)
  3626  	}
  3627  	c.pc += num
  3628  	offset, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  3629  	if err != nil {
  3630  		return memoryArg{}, fmt.Errorf("reading offset for %s: %w", tag, err)
  3631  	}
  3632  	c.pc += num
  3633  	return memoryArg{Offset: offset, Alignment: alignment}, nil
  3634  }