wa-lang.org/wazero@v1.0.2/internal/wazeroir/compiler.go (about)

     1  package wazeroir
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"encoding/binary"
     7  	"fmt"
     8  	"math"
     9  	"os"
    10  	"strings"
    11  
    12  	"wa-lang.org/wazero/api"
    13  	"wa-lang.org/wazero/internal/leb128"
    14  	"wa-lang.org/wazero/internal/wasm"
    15  )
    16  
    17  type controlFrameKind byte
    18  
    19  const (
    20  	controlFrameKindBlockWithContinuationLabel controlFrameKind = iota
    21  	controlFrameKindBlockWithoutContinuationLabel
    22  	controlFrameKindFunction
    23  	controlFrameKindLoop
    24  	controlFrameKindIfWithElse
    25  	controlFrameKindIfWithoutElse
    26  )
    27  
    28  type (
    29  	controlFrame struct {
    30  		frameID uint32
    31  		// originalStackLen holds the number of values on the stack
    32  		// when start executing this control frame minus params for the block.
    33  		originalStackLenWithoutParam int
    34  		blockType                    *wasm.FunctionType
    35  		kind                         controlFrameKind
    36  	}
    37  	controlFrames struct{ frames []*controlFrame }
    38  )
    39  
    40  func (c *controlFrame) ensureContinuation() {
    41  	// Make sure that if the frame is block and doesn't have continuation,
    42  	// change the kind so we can emit the continuation block
    43  	// later when we reach the end instruction of this frame.
    44  	if c.kind == controlFrameKindBlockWithoutContinuationLabel {
    45  		c.kind = controlFrameKindBlockWithContinuationLabel
    46  	}
    47  }
    48  
    49  func (c *controlFrame) asBranchTarget() *BranchTarget {
    50  	switch c.kind {
    51  	case controlFrameKindBlockWithContinuationLabel,
    52  		controlFrameKindBlockWithoutContinuationLabel:
    53  		return &BranchTarget{Label: &Label{FrameID: c.frameID, Kind: LabelKindContinuation}}
    54  	case controlFrameKindLoop:
    55  		return &BranchTarget{Label: &Label{FrameID: c.frameID, Kind: LabelKindHeader}}
    56  	case controlFrameKindFunction:
    57  		// Note nil target is translated as return.
    58  		return &BranchTarget{Label: nil}
    59  	case controlFrameKindIfWithElse,
    60  		controlFrameKindIfWithoutElse:
    61  		return &BranchTarget{Label: &Label{FrameID: c.frameID, Kind: LabelKindContinuation}}
    62  	}
    63  	panic(fmt.Sprintf("unreachable: a bug in wazeroir implementation: %v", c.kind))
    64  }
    65  
    66  func (c *controlFrames) functionFrame() *controlFrame {
    67  	// No need to check stack bound
    68  	// as we can assume that all the operations
    69  	// are valid thanks to validateFunction
    70  	// at module validation phase.
    71  	return c.frames[0]
    72  }
    73  
    74  func (c *controlFrames) get(n int) *controlFrame {
    75  	// No need to check stack bound
    76  	// as we can assume that all the operations
    77  	// are valid thanks to validateFunction
    78  	// at module validation phase.
    79  	return c.frames[len(c.frames)-n-1]
    80  }
    81  
    82  func (c *controlFrames) top() *controlFrame {
    83  	// No need to check stack bound
    84  	// as we can assume that all the operations
    85  	// are valid thanks to validateFunction
    86  	// at module validation phase.
    87  	return c.frames[len(c.frames)-1]
    88  }
    89  
    90  func (c *controlFrames) empty() bool {
    91  	return len(c.frames) == 0
    92  }
    93  
    94  func (c *controlFrames) pop() (frame *controlFrame) {
    95  	// No need to check stack bound
    96  	// as we can assume that all the operations
    97  	// are valid thanks to validateFunction
    98  	// at module validation phase.
    99  	frame = c.top()
   100  	c.frames = c.frames[:len(c.frames)-1]
   101  	return
   102  }
   103  
   104  func (c *controlFrames) push(frame *controlFrame) {
   105  	c.frames = append(c.frames, frame)
   106  }
   107  
   108  func (c *compiler) initializeStack() {
   109  	c.localIndexToStackHeightInUint64 = make(map[uint32]int, len(c.sig.Params)+len(c.localTypes))
   110  	var current int
   111  	for index, lt := range c.sig.Params {
   112  		c.localIndexToStackHeightInUint64[wasm.Index(index)] = current
   113  		if lt == wasm.ValueTypeV128 {
   114  			current++
   115  		}
   116  		current++
   117  	}
   118  
   119  	if c.callFrameStackSizeInUint64 > 0 {
   120  		// We reserve the stack slots for result values below the return call frame slots.
   121  		if diff := c.sig.ResultNumInUint64 - c.sig.ParamNumInUint64; diff > 0 {
   122  			current += diff
   123  		}
   124  	}
   125  
   126  	// Non-func param locals start after the return call frame.
   127  	current += c.callFrameStackSizeInUint64
   128  
   129  	for index, lt := range c.localTypes {
   130  		index += len(c.sig.Params)
   131  		c.localIndexToStackHeightInUint64[wasm.Index(index)] = current
   132  		if lt == wasm.ValueTypeV128 {
   133  			current++
   134  		}
   135  		current++
   136  	}
   137  
   138  	// Push function arguments.
   139  	for _, t := range c.sig.Params {
   140  		c.stackPush(wasmValueTypeToUnsignedType(t)...)
   141  	}
   142  
   143  	if c.callFrameStackSizeInUint64 > 0 {
   144  		// Reserve the stack slots for results.
   145  		for i := 0; i < c.sig.ResultNumInUint64-c.sig.ParamNumInUint64; i++ {
   146  			c.stackPush(UnsignedTypeI64)
   147  		}
   148  
   149  		// Reserve the stack slots for call frame.
   150  		for i := 0; i < c.callFrameStackSizeInUint64; i++ {
   151  			c.stackPush(UnsignedTypeI64)
   152  		}
   153  	}
   154  }
   155  
   156  type compiler struct {
   157  	enabledFeatures            api.CoreFeatures
   158  	callFrameStackSizeInUint64 int
   159  	stack                      []UnsignedType
   160  	currentID                  uint32
   161  	controlFrames              *controlFrames
   162  	unreachableState           struct {
   163  		on    bool
   164  		depth int
   165  	}
   166  	pc     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 map[wasm.Index]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 declard functions in the module where the targe function exists.
   182  	funcs []uint32
   183  	// globals holds the global types for all declard globas in the module where the targe function exists.
   184  	globals []*wasm.GlobalType
   185  }
   186  
   187  //lint:ignore U1000 for debugging only.
   188  func (c *compiler) stackDump() string {
   189  	strs := make([]string, 0, len(c.stack))
   190  	for _, s := range c.stack {
   191  		strs = append(strs, s.String())
   192  	}
   193  	return "[" + strings.Join(strs, ", ") + "]"
   194  }
   195  
   196  func (c *compiler) markUnreachable() {
   197  	c.unreachableState.on = true
   198  }
   199  
   200  func (c *compiler) resetUnreachable() {
   201  	c.unreachableState.on = false
   202  }
   203  
   204  type CompilationResult struct {
   205  	// IsHostFunction is the data returned by the same field documented on
   206  	// wasm.Code.
   207  	IsHostFunction bool
   208  
   209  	// GoFunc is the data returned by the same field documented on wasm.Code.
   210  	// In this case, IsHostFunction is true and other fields can be ignored.
   211  	GoFunc interface{}
   212  
   213  	// Operations holds wazeroir operations compiled from Wasm instructions in a Wasm function.
   214  	Operations []Operation
   215  
   216  	// LabelCallers maps Label.String() to the number of callers to that label.
   217  	// Here "callers" means that the call-sites which jumps to the label with br, br_if or br_table
   218  	// instructions.
   219  	//
   220  	// Note: zero possible and allowed in wasm. e.g.
   221  	//
   222  	//	(block
   223  	//	  (br 0)
   224  	//	  (block i32.const 1111)
   225  	//	)
   226  	//
   227  	// 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
   228  	LabelCallers map[string]uint32
   229  
   230  	// Signature is the function type of the compilation target function.
   231  	Signature *wasm.FunctionType
   232  	// Globals holds all the declarations of globals in the module from which this function is compiled.
   233  	Globals []*wasm.GlobalType
   234  	// Functions holds all the declarations of function in the module from which this function is compiled, including itself.
   235  	Functions []wasm.Index
   236  	// Types holds all the types in the module from which this function is compiled.
   237  	Types []*wasm.FunctionType
   238  	// TableTypes holds all the reference types of all tables declared in the module.
   239  	TableTypes []wasm.ValueType
   240  	// HasMemory is true if the module from which this function is compiled has memory declaration.
   241  	HasMemory bool
   242  	// UsesMemory is true if this function might use memory.
   243  	UsesMemory bool
   244  	// HasTable is true if the module from which this function is compiled has table declaration.
   245  	HasTable bool
   246  	// HasDataInstances is true if the module has data instances which might be used by memory.init or data.drop instructions.
   247  	HasDataInstances bool
   248  	// HasDataInstances is true if the module has element instances which might be used by table.init or elem.drop instructions.
   249  	HasElementInstances bool
   250  }
   251  
   252  func CompileFunctions(_ context.Context, enabledFeatures api.CoreFeatures, callFrameStackSizeInUint64 int, module *wasm.Module) ([]*CompilationResult, error) {
   253  	functions, globals, mem, tables, err := module.AllDeclarations()
   254  	if err != nil {
   255  		return nil, err
   256  	}
   257  
   258  	hasMemory, hasTable, hasDataInstances, hasElementInstances := mem != nil, len(tables) > 0,
   259  		len(module.DataSection) > 0, len(module.ElementSection) > 0
   260  
   261  	tableTypes := make([]wasm.ValueType, len(tables))
   262  	for i := range tableTypes {
   263  		tableTypes[i] = tables[i].Type
   264  	}
   265  
   266  	var ret []*CompilationResult
   267  	for funcIndex := range module.FunctionSection {
   268  		typeID := module.FunctionSection[funcIndex]
   269  		sig := module.TypeSection[typeID]
   270  		code := module.CodeSection[funcIndex]
   271  		if code.GoFunc != nil {
   272  			// Assume the function might use memory if it has a parameter for the api.Module
   273  			_, usesMemory := code.GoFunc.(api.GoModuleFunction)
   274  
   275  			ret = append(ret, &CompilationResult{
   276  				IsHostFunction: true,
   277  				UsesMemory:     usesMemory,
   278  				GoFunc:         code.GoFunc,
   279  				Signature:      sig,
   280  			})
   281  
   282  			if len(sig.Params) > 0 && sig.ParamNumInUint64 == 0 {
   283  				panic("a")
   284  			} else if len(sig.Results) > 0 && sig.ResultNumInUint64 == 0 {
   285  				panic("if len(sig.Results) > 0 && sig.ResultNumInUint64 == 0")
   286  			}
   287  			continue
   288  		}
   289  		r, err := compile(enabledFeatures, callFrameStackSizeInUint64, sig, code.Body, code.LocalTypes, module.TypeSection, functions, globals)
   290  		if err != nil {
   291  			def := module.FunctionDefinitionSection[uint32(funcIndex)+module.ImportFuncCount()]
   292  			return nil, fmt.Errorf("failed to lower func[%s] to wazeroir: %w", def.DebugName(), err)
   293  		}
   294  		r.IsHostFunction = code.IsHostFunction
   295  		r.Globals = globals
   296  		r.Functions = functions
   297  		r.Types = module.TypeSection
   298  		r.HasMemory = hasMemory
   299  		r.HasTable = hasTable
   300  		r.HasDataInstances = hasDataInstances
   301  		r.HasElementInstances = hasElementInstances
   302  		r.Signature = sig
   303  		r.TableTypes = tableTypes
   304  		ret = append(ret, r)
   305  	}
   306  	return ret, nil
   307  }
   308  
   309  // Compile lowers given function instance into wazeroir operations
   310  // so that the resulting operations can be consumed by the interpreter
   311  // or the Compiler compilation engine.
   312  func compile(enabledFeatures api.CoreFeatures,
   313  	callFrameStackSizeInUint64 int,
   314  	sig *wasm.FunctionType,
   315  	body []byte,
   316  	localTypes []wasm.ValueType,
   317  	types []*wasm.FunctionType,
   318  	functions []uint32, globals []*wasm.GlobalType,
   319  ) (*CompilationResult, error) {
   320  	c := compiler{
   321  		enabledFeatures:            enabledFeatures,
   322  		controlFrames:              &controlFrames{},
   323  		callFrameStackSizeInUint64: callFrameStackSizeInUint64,
   324  		result:                     CompilationResult{LabelCallers: map[string]uint32{}},
   325  		body:                       body,
   326  		localTypes:                 localTypes,
   327  		sig:                        sig,
   328  		globals:                    globals,
   329  		funcs:                      functions,
   330  		types:                      types,
   331  	}
   332  
   333  	c.initializeStack()
   334  
   335  	// Emit const expressions for locals.
   336  	// Note that here we don't take function arguments
   337  	// into account, meaning that callers must push
   338  	// arguments before entering into the function body.
   339  	for _, t := range localTypes {
   340  		c.emitDefaultValue(t)
   341  	}
   342  
   343  	// Insert the function control frame.
   344  	c.controlFrames.push(&controlFrame{
   345  		frameID:   c.nextID(),
   346  		blockType: c.sig,
   347  		kind:      controlFrameKindFunction,
   348  	})
   349  
   350  	// Now, enter the function body.
   351  	for !c.controlFrames.empty() && c.pc < uint64(len(c.body)) {
   352  		if err := c.handleInstruction(); err != nil {
   353  			return nil, fmt.Errorf("handling instruction: %w", err)
   354  		}
   355  	}
   356  	return &c.result, nil
   357  }
   358  
   359  // Translate the current Wasm instruction to wazeroir's operations,
   360  // and emit the results into c.results.
   361  func (c *compiler) handleInstruction() error {
   362  	op := c.body[c.pc]
   363  	if false {
   364  		var instName string
   365  		if op == wasm.OpcodeVecPrefix {
   366  			instName = wasm.VectorInstructionName(c.body[c.pc+1])
   367  		} else if op == wasm.OpcodeMiscPrefix {
   368  			instName = wasm.MiscInstructionName(c.body[c.pc+1])
   369  		} else {
   370  			instName = wasm.InstructionName(op)
   371  		}
   372  		fmt.Printf("handling %s, unreachable_state(on=%v,depth=%d), stack=%v\n",
   373  			instName, c.unreachableState.on, c.unreachableState.depth, c.stack,
   374  		)
   375  	}
   376  
   377  	var peekValueType UnsignedType
   378  	if len(c.stack) > 0 {
   379  		peekValueType = c.stackPeek()
   380  	}
   381  
   382  	// Modify the stack according the current instruction.
   383  	// Note that some instructions will read "index" in
   384  	// applyToStack and advance c.pc inside the function.
   385  	index, err := c.applyToStack(op)
   386  	if err != nil {
   387  		return fmt.Errorf("apply stack failed for %s: %w", wasm.InstructionName(op), err)
   388  	}
   389  	// Now we handle each instruction, and
   390  	// emit the corresponding wazeroir operations to the results.
   391  operatorSwitch:
   392  	switch op {
   393  	case wasm.OpcodeUnreachable:
   394  		c.emit(
   395  			&OperationUnreachable{},
   396  		)
   397  		c.markUnreachable()
   398  	case wasm.OpcodeNop:
   399  		// Nop is noop!
   400  	case wasm.OpcodeBlock:
   401  		bt, num, err := wasm.DecodeBlockType(c.types,
   402  			bytes.NewReader(c.body[c.pc+1:]), c.enabledFeatures)
   403  		if err != nil {
   404  			return fmt.Errorf("reading block type for block instruction: %w", err)
   405  		}
   406  		c.pc += num
   407  
   408  		if c.unreachableState.on {
   409  			// If it is currently in unreachable,
   410  			// just remove the entire block.
   411  			c.unreachableState.depth++
   412  			break operatorSwitch
   413  		}
   414  
   415  		// Create a new frame -- entering this block.
   416  		frame := &controlFrame{
   417  			frameID:                      c.nextID(),
   418  			originalStackLenWithoutParam: len(c.stack) - len(bt.Params),
   419  			kind:                         controlFrameKindBlockWithoutContinuationLabel,
   420  			blockType:                    bt,
   421  		}
   422  		c.controlFrames.push(frame)
   423  
   424  	case wasm.OpcodeLoop:
   425  		bt, num, err := wasm.DecodeBlockType(c.types, bytes.NewReader(c.body[c.pc+1:]), c.enabledFeatures)
   426  		if err != nil {
   427  			return fmt.Errorf("reading block type for loop instruction: %w", err)
   428  		}
   429  		c.pc += num
   430  
   431  		if c.unreachableState.on {
   432  			// If it is currently in unreachable,
   433  			// just remove the entire block.
   434  			c.unreachableState.depth++
   435  			break operatorSwitch
   436  		}
   437  
   438  		// Create a new frame -- entering loop.
   439  		frame := &controlFrame{
   440  			frameID:                      c.nextID(),
   441  			originalStackLenWithoutParam: len(c.stack) - len(bt.Params),
   442  			kind:                         controlFrameKindLoop,
   443  			blockType:                    bt,
   444  		}
   445  		c.controlFrames.push(frame)
   446  
   447  		// Prep labels for inside and the continuation of this loop.
   448  		loopLabel := &Label{FrameID: frame.frameID, Kind: LabelKindHeader}
   449  		c.result.LabelCallers[loopLabel.String()]++
   450  
   451  		// Emit the branch operation to enter inside the loop.
   452  		c.emit(
   453  			&OperationBr{
   454  				Target: loopLabel.asBranchTarget(),
   455  			},
   456  			&OperationLabel{Label: loopLabel},
   457  		)
   458  
   459  	case wasm.OpcodeIf:
   460  		bt, num, err := wasm.DecodeBlockType(c.types, bytes.NewReader(c.body[c.pc+1:]), c.enabledFeatures)
   461  		if err != nil {
   462  			return fmt.Errorf("reading block type for if instruction: %w", err)
   463  		}
   464  		c.pc += num
   465  
   466  		if c.unreachableState.on {
   467  			// If it is currently in unreachable,
   468  			// just remove the entire block.
   469  			c.unreachableState.depth++
   470  			break operatorSwitch
   471  		}
   472  
   473  		// Create a new frame -- entering if.
   474  		frame := &controlFrame{
   475  			frameID:                      c.nextID(),
   476  			originalStackLenWithoutParam: len(c.stack) - len(bt.Params),
   477  			// Note this will be set to controlFrameKindIfWithElse
   478  			// when else opcode found later.
   479  			kind:      controlFrameKindIfWithoutElse,
   480  			blockType: bt,
   481  		}
   482  		c.controlFrames.push(frame)
   483  
   484  		// Prep labels for if and else of this if.
   485  		thenLabel := &Label{Kind: LabelKindHeader, FrameID: frame.frameID}
   486  		elseLabel := &Label{Kind: LabelKindElse, FrameID: frame.frameID}
   487  		c.result.LabelCallers[thenLabel.String()]++
   488  		c.result.LabelCallers[elseLabel.String()]++
   489  
   490  		// Emit the branch operation to enter the then block.
   491  		c.emit(
   492  			&OperationBrIf{
   493  				Then: thenLabel.asBranchTargetDrop(),
   494  				Else: elseLabel.asBranchTargetDrop(),
   495  			},
   496  			&OperationLabel{
   497  				Label: thenLabel,
   498  			},
   499  		)
   500  	case wasm.OpcodeElse:
   501  		frame := c.controlFrames.top()
   502  		if c.unreachableState.on && c.unreachableState.depth > 0 {
   503  			// If it is currently in unreachable, and the nested if,
   504  			// just remove the entire else block.
   505  			break operatorSwitch
   506  		} else if c.unreachableState.on {
   507  			// If it is currently in unreachable, and the non-nested if,
   508  			// reset the stack so we can correctly handle the else block.
   509  			top := c.controlFrames.top()
   510  			c.stack = c.stack[:top.originalStackLenWithoutParam]
   511  			top.kind = controlFrameKindIfWithElse
   512  
   513  			// Re-push the parameters to the if block so that else block can use them.
   514  			for _, t := range frame.blockType.Params {
   515  				c.stackPush(wasmValueTypeToUnsignedType(t)...)
   516  			}
   517  
   518  			// We are no longer unreachable in else frame,
   519  			// so emit the correct label, and reset the unreachable state.
   520  			elseLabel := &Label{FrameID: frame.frameID, Kind: LabelKindElse}
   521  			c.resetUnreachable()
   522  			c.emit(
   523  				&OperationLabel{Label: elseLabel},
   524  			)
   525  			break operatorSwitch
   526  		}
   527  
   528  		// Change the kind of this If block, indicating that
   529  		// the if has else block.
   530  		frame.kind = controlFrameKindIfWithElse
   531  
   532  		// We need to reset the stack so that
   533  		// the values pushed inside the then block
   534  		// do not affect the else block.
   535  		dropOp := &OperationDrop{Depth: c.getFrameDropRange(frame, false)}
   536  
   537  		// Reset the stack manipulated by the then block, and re-push the block param types to the stack.
   538  
   539  		c.stack = c.stack[:frame.originalStackLenWithoutParam]
   540  		for _, t := range frame.blockType.Params {
   541  			c.stackPush(wasmValueTypeToUnsignedType(t)...)
   542  		}
   543  
   544  		// Prep labels for else and the continuation of this if block.
   545  		elseLabel := &Label{FrameID: frame.frameID, Kind: LabelKindElse}
   546  		continuationLabel := &Label{FrameID: frame.frameID, Kind: LabelKindContinuation}
   547  		c.result.LabelCallers[continuationLabel.String()]++
   548  
   549  		// Emit the instructions for exiting the if loop,
   550  		// and then the initiation of else block.
   551  		c.emit(
   552  			dropOp,
   553  			// Jump to the continuation of this block.
   554  			&OperationBr{Target: continuationLabel.asBranchTarget()},
   555  			// Initiate the else block.
   556  			&OperationLabel{Label: elseLabel},
   557  		)
   558  	case wasm.OpcodeEnd:
   559  		if c.unreachableState.on && c.unreachableState.depth > 0 {
   560  			c.unreachableState.depth--
   561  			break operatorSwitch
   562  		} else if c.unreachableState.on {
   563  			c.resetUnreachable()
   564  
   565  			frame := c.controlFrames.pop()
   566  			if c.controlFrames.empty() {
   567  				return nil
   568  			}
   569  
   570  			c.stack = c.stack[:frame.originalStackLenWithoutParam]
   571  			for _, t := range frame.blockType.Results {
   572  				c.stackPush(wasmValueTypeToUnsignedType(t)...)
   573  			}
   574  
   575  			continuationLabel := &Label{FrameID: frame.frameID, Kind: LabelKindContinuation}
   576  			if frame.kind == controlFrameKindIfWithoutElse {
   577  				// Emit the else label.
   578  				elseLabel := &Label{Kind: LabelKindElse, FrameID: frame.frameID}
   579  				c.result.LabelCallers[continuationLabel.String()]++
   580  				c.emit(
   581  					&OperationLabel{Label: elseLabel},
   582  					&OperationBr{Target: continuationLabel.asBranchTarget()},
   583  					&OperationLabel{Label: continuationLabel},
   584  				)
   585  			} else {
   586  				c.emit(
   587  					&OperationLabel{Label: continuationLabel},
   588  				)
   589  			}
   590  
   591  			break operatorSwitch
   592  		}
   593  
   594  		frame := c.controlFrames.pop()
   595  
   596  		// We need to reset the stack so that
   597  		// the values pushed inside the block.
   598  		dropOp := &OperationDrop{Depth: c.getFrameDropRange(frame, true)}
   599  		c.stack = c.stack[:frame.originalStackLenWithoutParam]
   600  
   601  		// Push the result types onto the stack.
   602  		for _, t := range frame.blockType.Results {
   603  			c.stackPush(wasmValueTypeToUnsignedType(t)...)
   604  		}
   605  
   606  		// Emit the instructions according to the kind of the current control frame.
   607  		switch frame.kind {
   608  		case controlFrameKindFunction:
   609  			if !c.controlFrames.empty() {
   610  				// Should never happen. If so, there's a bug in the translation.
   611  				panic("bug: found more function control frames")
   612  			}
   613  			// Return from function.
   614  			c.emit(
   615  				dropOp,
   616  				// Pass empty target instead of nil to avoid misinterpretation as "return"
   617  				&OperationBr{Target: &BranchTarget{}},
   618  			)
   619  		case controlFrameKindIfWithoutElse:
   620  			// This case we have to emit "empty" else label.
   621  			elseLabel := &Label{Kind: LabelKindElse, FrameID: frame.frameID}
   622  			continuationLabel := &Label{Kind: LabelKindContinuation, FrameID: frame.frameID}
   623  			c.result.LabelCallers[continuationLabel.String()] += 2
   624  			c.emit(
   625  				dropOp,
   626  				&OperationBr{Target: continuationLabel.asBranchTarget()},
   627  				// Emit the else which soon branches into the continuation.
   628  				&OperationLabel{Label: elseLabel},
   629  				&OperationBr{Target: continuationLabel.asBranchTarget()},
   630  				// Initiate the continuation.
   631  				&OperationLabel{Label: continuationLabel},
   632  			)
   633  		case controlFrameKindBlockWithContinuationLabel,
   634  			controlFrameKindIfWithElse:
   635  			continuationLabel := &Label{Kind: LabelKindContinuation, FrameID: frame.frameID}
   636  			c.result.LabelCallers[continuationLabel.String()]++
   637  			c.emit(
   638  				dropOp,
   639  				&OperationBr{Target: continuationLabel.asBranchTarget()},
   640  				&OperationLabel{Label: continuationLabel},
   641  			)
   642  		case controlFrameKindLoop, controlFrameKindBlockWithoutContinuationLabel:
   643  			c.emit(
   644  				dropOp,
   645  			)
   646  		default:
   647  			// Should never happen. If so, there's a bug in the translation.
   648  			panic(fmt.Errorf("bug: invalid control frame kind: 0x%x", frame.kind))
   649  		}
   650  
   651  	case wasm.OpcodeBr:
   652  		targetIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:])
   653  		if err != nil {
   654  			return fmt.Errorf("read the target for br_if: %w", err)
   655  		}
   656  		c.pc += n
   657  
   658  		if c.unreachableState.on {
   659  			// If it is currently in unreachable, br is no-op.
   660  			break operatorSwitch
   661  		}
   662  
   663  		targetFrame := c.controlFrames.get(int(targetIndex))
   664  		targetFrame.ensureContinuation()
   665  		dropOp := &OperationDrop{Depth: c.getFrameDropRange(targetFrame, false)}
   666  		target := targetFrame.asBranchTarget()
   667  		c.result.LabelCallers[target.Label.String()]++
   668  		c.emit(
   669  			dropOp,
   670  			&OperationBr{Target: target},
   671  		)
   672  		// Br operation is stack-polymorphic, and mark the state as unreachable.
   673  		// That means subsequent instructions in the current control frame are "unreachable"
   674  		// and can be safely removed.
   675  		c.markUnreachable()
   676  	case wasm.OpcodeBrIf:
   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-if is no-op.
   685  			break operatorSwitch
   686  		}
   687  
   688  		targetFrame := c.controlFrames.get(int(targetIndex))
   689  		targetFrame.ensureContinuation()
   690  		drop := c.getFrameDropRange(targetFrame, false)
   691  		target := targetFrame.asBranchTarget()
   692  		c.result.LabelCallers[target.Label.String()]++
   693  
   694  		continuationLabel := &Label{FrameID: c.nextID(), Kind: LabelKindHeader}
   695  		c.result.LabelCallers[continuationLabel.String()]++
   696  		c.emit(
   697  			&OperationBrIf{
   698  				Then: &BranchTargetDrop{ToDrop: drop, Target: target},
   699  				Else: continuationLabel.asBranchTargetDrop(),
   700  			},
   701  			// Start emitting else block operations.
   702  			&OperationLabel{
   703  				Label: continuationLabel,
   704  			},
   705  		)
   706  	case wasm.OpcodeBrTable:
   707  		r := bytes.NewReader(c.body[c.pc+1:])
   708  		numTargets, n, err := leb128.DecodeUint32(r)
   709  		if err != nil {
   710  			return fmt.Errorf("error reading number of targets in br_table: %w", err)
   711  		}
   712  		c.pc += n
   713  
   714  		if c.unreachableState.on {
   715  			// If it is currently in unreachable, br_table is no-op.
   716  			// But before proceeding to the next instruction, we must advance the pc
   717  			// according to the number of br_table targets.
   718  			for i := uint32(0); i <= numTargets; i++ { // inclusive as we also need to read the index of default target.
   719  				_, n, err := leb128.DecodeUint32(r)
   720  				if err != nil {
   721  					return fmt.Errorf("error reading target %d in br_table: %w", i, err)
   722  				}
   723  				c.pc += n
   724  			}
   725  			break operatorSwitch
   726  		}
   727  
   728  		// Read the branch targets.
   729  		targets := make([]*BranchTargetDrop, numTargets)
   730  		for i := range targets {
   731  			l, n, err := leb128.DecodeUint32(r)
   732  			if err != nil {
   733  				return fmt.Errorf("error reading target %d in br_table: %w", i, err)
   734  			}
   735  			c.pc += n
   736  			targetFrame := c.controlFrames.get(int(l))
   737  			targetFrame.ensureContinuation()
   738  			drop := c.getFrameDropRange(targetFrame, false)
   739  			target := &BranchTargetDrop{ToDrop: drop, Target: targetFrame.asBranchTarget()}
   740  			targets[i] = target
   741  			c.result.LabelCallers[target.Target.Label.String()]++
   742  		}
   743  
   744  		// Prep default target control frame.
   745  		l, n, err := leb128.DecodeUint32(r)
   746  		if err != nil {
   747  			return fmt.Errorf("error reading default target of br_table: %w", err)
   748  		}
   749  		c.pc += n
   750  		defaultTargetFrame := c.controlFrames.get(int(l))
   751  		defaultTargetFrame.ensureContinuation()
   752  		defaultTargetDrop := c.getFrameDropRange(defaultTargetFrame, false)
   753  		defaultTarget := defaultTargetFrame.asBranchTarget()
   754  		c.result.LabelCallers[defaultTarget.Label.String()]++
   755  
   756  		c.emit(
   757  			&OperationBrTable{
   758  				Targets: targets,
   759  				Default: &BranchTargetDrop{
   760  					ToDrop: defaultTargetDrop, Target: defaultTarget,
   761  				},
   762  			},
   763  		)
   764  		// Br operation is stack-polymorphic, and mark the state as unreachable.
   765  		// That means subsequent instructions in the current control frame are "unreachable"
   766  		// and can be safely removed.
   767  		c.markUnreachable()
   768  	case wasm.OpcodeReturn:
   769  		functionFrame := c.controlFrames.functionFrame()
   770  		dropOp := &OperationDrop{Depth: c.getFrameDropRange(functionFrame, false)}
   771  
   772  		// Cleanup the stack and then jmp to function frame's continuation (meaning return).
   773  		c.emit(
   774  			dropOp,
   775  			&OperationBr{Target: functionFrame.asBranchTarget()},
   776  		)
   777  
   778  		// Return 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.OpcodeCall:
   783  		if index == nil {
   784  			return fmt.Errorf("index does not exist for function call")
   785  		}
   786  		c.emit(
   787  			&OperationCall{FunctionIndex: *index},
   788  		)
   789  	case wasm.OpcodeCallIndirect:
   790  		if index == nil {
   791  			return fmt.Errorf("index does not exist for indirect function call")
   792  		}
   793  		tableIndex, n, err := leb128.LoadUint32(c.body[c.pc+1:])
   794  		if err != nil {
   795  			return fmt.Errorf("read target for br_table: %w", err)
   796  		}
   797  		c.pc += n
   798  		c.emit(
   799  			&OperationCallIndirect{TypeIndex: *index, TableIndex: tableIndex},
   800  		)
   801  	case wasm.OpcodeDrop:
   802  		r := &InclusiveRange{Start: 0, End: 0}
   803  		if peekValueType == UnsignedTypeV128 {
   804  			// InclusiveRange is the range in uint64 representation, so dropping a vector value on top
   805  			// should be translated as drop [0..1] inclusively.
   806  			r.End++
   807  		}
   808  		c.emit(
   809  			&OperationDrop{Depth: r},
   810  		)
   811  	case wasm.OpcodeSelect:
   812  		// If it is on the unreachable state, ignore the instruction.
   813  		if c.unreachableState.on {
   814  			break operatorSwitch
   815  		}
   816  		c.emit(
   817  			&OperationSelect{IsTargetVector: c.stackPeek() == UnsignedTypeV128},
   818  		)
   819  	case wasm.OpcodeTypedSelect:
   820  		// Skips two bytes: vector size fixed to 1, and the value type for select.
   821  		c.pc += 2
   822  		// If it is on the unreachable state, ignore the instruction.
   823  		if c.unreachableState.on {
   824  			break operatorSwitch
   825  		}
   826  		// Typed select is semantically equivalent to select at runtime.
   827  		c.emit(
   828  			&OperationSelect{IsTargetVector: c.stackPeek() == UnsignedTypeV128},
   829  		)
   830  	case wasm.OpcodeLocalGet:
   831  		if index == nil {
   832  			return fmt.Errorf("index does not exist for local.get")
   833  		}
   834  		id := *index
   835  		depth := c.localDepth(id)
   836  		if isVector := c.localType(id) == wasm.ValueTypeV128; !isVector {
   837  			c.emit(
   838  				// -1 because we already manipulated the stack before
   839  				// called localDepth ^^.
   840  				&OperationPick{Depth: depth - 1, IsTargetVector: isVector},
   841  			)
   842  		} else {
   843  			c.emit(
   844  				// -2 because we already manipulated the stack before
   845  				// called localDepth ^^.
   846  				&OperationPick{Depth: depth - 2, IsTargetVector: isVector},
   847  			)
   848  		}
   849  	case wasm.OpcodeLocalSet:
   850  		if index == nil {
   851  			return fmt.Errorf("index does not exist for local.set")
   852  		}
   853  		id := *index
   854  		depth := c.localDepth(id)
   855  
   856  		isVector := c.localType(id) == wasm.ValueTypeV128
   857  		if isVector {
   858  			c.emit(
   859  				// +2 because we already popped the operands for this operation from the c.stack before
   860  				// called localDepth ^^,
   861  				&OperationSet{Depth: depth + 2, IsTargetVector: isVector},
   862  			)
   863  		} else {
   864  			c.emit(
   865  				// +1 because we already popped the operands for this operation from the c.stack before
   866  				// called localDepth ^^,
   867  				&OperationSet{Depth: depth + 1, IsTargetVector: isVector},
   868  			)
   869  		}
   870  	case wasm.OpcodeLocalTee:
   871  		if index == nil {
   872  			return fmt.Errorf("index does not exist for local.tee")
   873  		}
   874  		id := *index
   875  		depth := c.localDepth(id)
   876  		isVector := c.localType(id) == wasm.ValueTypeV128
   877  		if isVector {
   878  			c.emit(
   879  				&OperationPick{Depth: 1, IsTargetVector: isVector},
   880  				&OperationSet{Depth: depth + 2, IsTargetVector: isVector},
   881  			)
   882  		} else {
   883  			c.emit(
   884  				&OperationPick{Depth: 0, IsTargetVector: isVector},
   885  				&OperationSet{Depth: depth + 1, IsTargetVector: isVector},
   886  			)
   887  		}
   888  	case wasm.OpcodeGlobalGet:
   889  		if index == nil {
   890  			return fmt.Errorf("index does not exist for global.get")
   891  		}
   892  		c.emit(
   893  			&OperationGlobalGet{Index: *index},
   894  		)
   895  	case wasm.OpcodeGlobalSet:
   896  		if index == nil {
   897  			return fmt.Errorf("index does not exist for global.set")
   898  		}
   899  		c.emit(
   900  			&OperationGlobalSet{Index: *index},
   901  		)
   902  	case wasm.OpcodeI32Load:
   903  		imm, err := c.readMemoryArg(wasm.OpcodeI32LoadName)
   904  		if err != nil {
   905  			return err
   906  		}
   907  		c.emit(
   908  			&OperationLoad{Type: UnsignedTypeI32, Arg: imm},
   909  		)
   910  	case wasm.OpcodeI64Load:
   911  		imm, err := c.readMemoryArg(wasm.OpcodeI64LoadName)
   912  		if err != nil {
   913  			return err
   914  		}
   915  		c.emit(
   916  			&OperationLoad{Type: UnsignedTypeI64, Arg: imm},
   917  		)
   918  	case wasm.OpcodeF32Load:
   919  		imm, err := c.readMemoryArg(wasm.OpcodeF32LoadName)
   920  		if err != nil {
   921  			return err
   922  		}
   923  		c.emit(
   924  			&OperationLoad{Type: UnsignedTypeF32, Arg: imm},
   925  		)
   926  	case wasm.OpcodeF64Load:
   927  		imm, err := c.readMemoryArg(wasm.OpcodeF64LoadName)
   928  		if err != nil {
   929  			return err
   930  		}
   931  		c.emit(
   932  			&OperationLoad{Type: UnsignedTypeF64, Arg: imm},
   933  		)
   934  	case wasm.OpcodeI32Load8S:
   935  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load8SName)
   936  		if err != nil {
   937  			return err
   938  		}
   939  		c.emit(
   940  			&OperationLoad8{Type: SignedInt32, Arg: imm},
   941  		)
   942  	case wasm.OpcodeI32Load8U:
   943  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load8UName)
   944  		if err != nil {
   945  			return err
   946  		}
   947  		c.emit(
   948  			&OperationLoad8{Type: SignedUint32, Arg: imm},
   949  		)
   950  	case wasm.OpcodeI32Load16S:
   951  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load16SName)
   952  		if err != nil {
   953  			return err
   954  		}
   955  		c.emit(
   956  			&OperationLoad16{Type: SignedInt32, Arg: imm},
   957  		)
   958  	case wasm.OpcodeI32Load16U:
   959  		imm, err := c.readMemoryArg(wasm.OpcodeI32Load16UName)
   960  		if err != nil {
   961  			return err
   962  		}
   963  		c.emit(
   964  			&OperationLoad16{Type: SignedUint32, Arg: imm},
   965  		)
   966  	case wasm.OpcodeI64Load8S:
   967  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load8SName)
   968  		if err != nil {
   969  			return err
   970  		}
   971  		c.emit(
   972  			&OperationLoad8{Type: SignedInt64, Arg: imm},
   973  		)
   974  	case wasm.OpcodeI64Load8U:
   975  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load8UName)
   976  		if err != nil {
   977  			return err
   978  		}
   979  		c.emit(
   980  			&OperationLoad8{Type: SignedUint64, Arg: imm},
   981  		)
   982  	case wasm.OpcodeI64Load16S:
   983  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load16SName)
   984  		if err != nil {
   985  			return err
   986  		}
   987  		c.emit(
   988  			&OperationLoad16{Type: SignedInt64, Arg: imm},
   989  		)
   990  	case wasm.OpcodeI64Load16U:
   991  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load16UName)
   992  		if err != nil {
   993  			return err
   994  		}
   995  		c.emit(
   996  			&OperationLoad16{Type: SignedUint64, Arg: imm},
   997  		)
   998  	case wasm.OpcodeI64Load32S:
   999  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load32SName)
  1000  		if err != nil {
  1001  			return err
  1002  		}
  1003  		c.emit(
  1004  			&OperationLoad32{Signed: true, Arg: imm},
  1005  		)
  1006  	case wasm.OpcodeI64Load32U:
  1007  		imm, err := c.readMemoryArg(wasm.OpcodeI64Load32UName)
  1008  		if err != nil {
  1009  			return err
  1010  		}
  1011  		c.emit(
  1012  			&OperationLoad32{Signed: false, Arg: imm},
  1013  		)
  1014  	case wasm.OpcodeI32Store:
  1015  		imm, err := c.readMemoryArg(wasm.OpcodeI32StoreName)
  1016  		if err != nil {
  1017  			return err
  1018  		}
  1019  		c.emit(
  1020  			&OperationStore{Type: UnsignedTypeI32, Arg: imm},
  1021  		)
  1022  	case wasm.OpcodeI64Store:
  1023  		imm, err := c.readMemoryArg(wasm.OpcodeI64StoreName)
  1024  		if err != nil {
  1025  			return err
  1026  		}
  1027  		c.emit(
  1028  			&OperationStore{Type: UnsignedTypeI64, Arg: imm},
  1029  		)
  1030  	case wasm.OpcodeF32Store:
  1031  		imm, err := c.readMemoryArg(wasm.OpcodeF32StoreName)
  1032  		if err != nil {
  1033  			return err
  1034  		}
  1035  		c.emit(
  1036  			&OperationStore{Type: UnsignedTypeF32, Arg: imm},
  1037  		)
  1038  	case wasm.OpcodeF64Store:
  1039  		imm, err := c.readMemoryArg(wasm.OpcodeF64StoreName)
  1040  		if err != nil {
  1041  			return err
  1042  		}
  1043  		c.emit(
  1044  			&OperationStore{Type: UnsignedTypeF64, Arg: imm},
  1045  		)
  1046  	case wasm.OpcodeI32Store8:
  1047  		imm, err := c.readMemoryArg(wasm.OpcodeI32Store8Name)
  1048  		if err != nil {
  1049  			return err
  1050  		}
  1051  		c.emit(
  1052  			&OperationStore8{Arg: imm},
  1053  		)
  1054  	case wasm.OpcodeI32Store16:
  1055  		imm, err := c.readMemoryArg(wasm.OpcodeI32Store16Name)
  1056  		if err != nil {
  1057  			return err
  1058  		}
  1059  		c.emit(
  1060  			&OperationStore16{Arg: imm},
  1061  		)
  1062  	case wasm.OpcodeI64Store8:
  1063  		imm, err := c.readMemoryArg(wasm.OpcodeI64Store8Name)
  1064  		if err != nil {
  1065  			return err
  1066  		}
  1067  		c.emit(
  1068  			&OperationStore8{Arg: imm},
  1069  		)
  1070  	case wasm.OpcodeI64Store16:
  1071  		imm, err := c.readMemoryArg(wasm.OpcodeI64Store16Name)
  1072  		if err != nil {
  1073  			return err
  1074  		}
  1075  		c.emit(
  1076  			&OperationStore16{Arg: imm},
  1077  		)
  1078  	case wasm.OpcodeI64Store32:
  1079  		imm, err := c.readMemoryArg(wasm.OpcodeI64Store32Name)
  1080  		if err != nil {
  1081  			return err
  1082  		}
  1083  		c.emit(
  1084  			&OperationStore32{Arg: imm},
  1085  		)
  1086  	case wasm.OpcodeMemorySize:
  1087  		c.result.UsesMemory = true
  1088  		c.pc++ // Skip the reserved one byte.
  1089  		c.emit(
  1090  			&OperationMemorySize{},
  1091  		)
  1092  	case wasm.OpcodeMemoryGrow:
  1093  		c.result.UsesMemory = true
  1094  		c.pc++ // Skip the reserved one byte.
  1095  		c.emit(
  1096  			&OperationMemoryGrow{},
  1097  		)
  1098  	case wasm.OpcodeI32Const:
  1099  		val, num, err := leb128.LoadInt32(c.body[c.pc+1:])
  1100  		if err != nil {
  1101  			return fmt.Errorf("reading i32.const value: %v", err)
  1102  		}
  1103  		c.pc += num
  1104  		c.emit(
  1105  			&OperationConstI32{Value: uint32(val)},
  1106  		)
  1107  	case wasm.OpcodeI64Const:
  1108  		val, num, err := leb128.LoadInt64(c.body[c.pc+1:])
  1109  		if err != nil {
  1110  			return fmt.Errorf("reading i64.const value: %v", err)
  1111  		}
  1112  		c.pc += num
  1113  		c.emit(
  1114  			&OperationConstI64{Value: uint64(val)},
  1115  		)
  1116  	case wasm.OpcodeF32Const:
  1117  		v := math.Float32frombits(binary.LittleEndian.Uint32(c.body[c.pc+1:]))
  1118  		c.pc += 4
  1119  		c.emit(
  1120  			&OperationConstF32{Value: v},
  1121  		)
  1122  	case wasm.OpcodeF64Const:
  1123  		v := math.Float64frombits(binary.LittleEndian.Uint64(c.body[c.pc+1:]))
  1124  		c.pc += 8
  1125  		c.emit(
  1126  			&OperationConstF64{Value: v},
  1127  		)
  1128  	case wasm.OpcodeI32Eqz:
  1129  		c.emit(
  1130  			&OperationEqz{Type: UnsignedInt32},
  1131  		)
  1132  	case wasm.OpcodeI32Eq:
  1133  		c.emit(
  1134  			&OperationEq{Type: UnsignedTypeI32},
  1135  		)
  1136  	case wasm.OpcodeI32Ne:
  1137  		c.emit(
  1138  			&OperationNe{Type: UnsignedTypeI32},
  1139  		)
  1140  	case wasm.OpcodeI32LtS:
  1141  		c.emit(
  1142  			&OperationLt{Type: SignedTypeInt32},
  1143  		)
  1144  	case wasm.OpcodeI32LtU:
  1145  		c.emit(
  1146  			&OperationLt{Type: SignedTypeUint32},
  1147  		)
  1148  	case wasm.OpcodeI32GtS:
  1149  		c.emit(
  1150  			&OperationGt{Type: SignedTypeInt32},
  1151  		)
  1152  	case wasm.OpcodeI32GtU:
  1153  		c.emit(
  1154  			&OperationGt{Type: SignedTypeUint32},
  1155  		)
  1156  	case wasm.OpcodeI32LeS:
  1157  		c.emit(
  1158  			&OperationLe{Type: SignedTypeInt32},
  1159  		)
  1160  	case wasm.OpcodeI32LeU:
  1161  		c.emit(
  1162  			&OperationLe{Type: SignedTypeUint32},
  1163  		)
  1164  	case wasm.OpcodeI32GeS:
  1165  		c.emit(
  1166  			&OperationGe{Type: SignedTypeInt32},
  1167  		)
  1168  	case wasm.OpcodeI32GeU:
  1169  		c.emit(
  1170  			&OperationGe{Type: SignedTypeUint32},
  1171  		)
  1172  	case wasm.OpcodeI64Eqz:
  1173  		c.emit(
  1174  			&OperationEqz{Type: UnsignedInt64},
  1175  		)
  1176  	case wasm.OpcodeI64Eq:
  1177  		c.emit(
  1178  			&OperationEq{Type: UnsignedTypeI64},
  1179  		)
  1180  	case wasm.OpcodeI64Ne:
  1181  		c.emit(
  1182  			&OperationNe{Type: UnsignedTypeI64},
  1183  		)
  1184  	case wasm.OpcodeI64LtS:
  1185  		c.emit(
  1186  			&OperationLt{Type: SignedTypeInt64},
  1187  		)
  1188  	case wasm.OpcodeI64LtU:
  1189  		c.emit(
  1190  			&OperationLt{Type: SignedTypeUint64},
  1191  		)
  1192  	case wasm.OpcodeI64GtS:
  1193  		c.emit(
  1194  			&OperationGt{Type: SignedTypeInt64},
  1195  		)
  1196  	case wasm.OpcodeI64GtU:
  1197  		c.emit(
  1198  			&OperationGt{Type: SignedTypeUint64},
  1199  		)
  1200  	case wasm.OpcodeI64LeS:
  1201  		c.emit(
  1202  			&OperationLe{Type: SignedTypeInt64},
  1203  		)
  1204  	case wasm.OpcodeI64LeU:
  1205  		c.emit(
  1206  			&OperationLe{Type: SignedTypeUint64},
  1207  		)
  1208  	case wasm.OpcodeI64GeS:
  1209  		c.emit(
  1210  			&OperationGe{Type: SignedTypeInt64},
  1211  		)
  1212  	case wasm.OpcodeI64GeU:
  1213  		c.emit(
  1214  			&OperationGe{Type: SignedTypeUint64},
  1215  		)
  1216  	case wasm.OpcodeF32Eq:
  1217  		c.emit(
  1218  			&OperationEq{Type: UnsignedTypeF32},
  1219  		)
  1220  	case wasm.OpcodeF32Ne:
  1221  		c.emit(
  1222  			&OperationNe{Type: UnsignedTypeF32},
  1223  		)
  1224  	case wasm.OpcodeF32Lt:
  1225  		c.emit(
  1226  			&OperationLt{Type: SignedTypeFloat32},
  1227  		)
  1228  	case wasm.OpcodeF32Gt:
  1229  		c.emit(
  1230  			&OperationGt{Type: SignedTypeFloat32},
  1231  		)
  1232  	case wasm.OpcodeF32Le:
  1233  		c.emit(
  1234  			&OperationLe{Type: SignedTypeFloat32},
  1235  		)
  1236  	case wasm.OpcodeF32Ge:
  1237  		c.emit(
  1238  			&OperationGe{Type: SignedTypeFloat32},
  1239  		)
  1240  	case wasm.OpcodeF64Eq:
  1241  		c.emit(
  1242  			&OperationEq{Type: UnsignedTypeF64},
  1243  		)
  1244  	case wasm.OpcodeF64Ne:
  1245  		c.emit(
  1246  			&OperationNe{Type: UnsignedTypeF64},
  1247  		)
  1248  	case wasm.OpcodeF64Lt:
  1249  		c.emit(
  1250  			&OperationLt{Type: SignedTypeFloat64},
  1251  		)
  1252  	case wasm.OpcodeF64Gt:
  1253  		c.emit(
  1254  			&OperationGt{Type: SignedTypeFloat64},
  1255  		)
  1256  	case wasm.OpcodeF64Le:
  1257  		c.emit(
  1258  			&OperationLe{Type: SignedTypeFloat64},
  1259  		)
  1260  	case wasm.OpcodeF64Ge:
  1261  		c.emit(
  1262  			&OperationGe{Type: SignedTypeFloat64},
  1263  		)
  1264  	case wasm.OpcodeI32Clz:
  1265  		c.emit(
  1266  			&OperationClz{Type: UnsignedInt32},
  1267  		)
  1268  	case wasm.OpcodeI32Ctz:
  1269  		c.emit(
  1270  			&OperationCtz{Type: UnsignedInt32},
  1271  		)
  1272  	case wasm.OpcodeI32Popcnt:
  1273  		c.emit(
  1274  			&OperationPopcnt{Type: UnsignedInt32},
  1275  		)
  1276  	case wasm.OpcodeI32Add:
  1277  		c.emit(
  1278  			&OperationAdd{Type: UnsignedTypeI32},
  1279  		)
  1280  	case wasm.OpcodeI32Sub:
  1281  		c.emit(
  1282  			&OperationSub{Type: UnsignedTypeI32},
  1283  		)
  1284  	case wasm.OpcodeI32Mul:
  1285  		c.emit(
  1286  			&OperationMul{Type: UnsignedTypeI32},
  1287  		)
  1288  	case wasm.OpcodeI32DivS:
  1289  		c.emit(
  1290  			&OperationDiv{Type: SignedTypeInt32},
  1291  		)
  1292  	case wasm.OpcodeI32DivU:
  1293  		c.emit(
  1294  			&OperationDiv{Type: SignedTypeUint32},
  1295  		)
  1296  	case wasm.OpcodeI32RemS:
  1297  		c.emit(
  1298  			&OperationRem{Type: SignedInt32},
  1299  		)
  1300  	case wasm.OpcodeI32RemU:
  1301  		c.emit(
  1302  			&OperationRem{Type: SignedUint32},
  1303  		)
  1304  	case wasm.OpcodeI32And:
  1305  		c.emit(
  1306  			&OperationAnd{Type: UnsignedInt32},
  1307  		)
  1308  	case wasm.OpcodeI32Or:
  1309  		c.emit(
  1310  			&OperationOr{Type: UnsignedInt32},
  1311  		)
  1312  	case wasm.OpcodeI32Xor:
  1313  		c.emit(
  1314  			&OperationXor{Type: UnsignedInt64},
  1315  		)
  1316  	case wasm.OpcodeI32Shl:
  1317  		c.emit(
  1318  			&OperationShl{Type: UnsignedInt32},
  1319  		)
  1320  	case wasm.OpcodeI32ShrS:
  1321  		c.emit(
  1322  			&OperationShr{Type: SignedInt32},
  1323  		)
  1324  	case wasm.OpcodeI32ShrU:
  1325  		c.emit(
  1326  			&OperationShr{Type: SignedUint32},
  1327  		)
  1328  	case wasm.OpcodeI32Rotl:
  1329  		c.emit(
  1330  			&OperationRotl{Type: UnsignedInt32},
  1331  		)
  1332  	case wasm.OpcodeI32Rotr:
  1333  		c.emit(
  1334  			&OperationRotr{Type: UnsignedInt32},
  1335  		)
  1336  	case wasm.OpcodeI64Clz:
  1337  		c.emit(
  1338  			&OperationClz{Type: UnsignedInt64},
  1339  		)
  1340  	case wasm.OpcodeI64Ctz:
  1341  		c.emit(
  1342  			&OperationCtz{Type: UnsignedInt64},
  1343  		)
  1344  	case wasm.OpcodeI64Popcnt:
  1345  		c.emit(
  1346  			&OperationPopcnt{Type: UnsignedInt64},
  1347  		)
  1348  	case wasm.OpcodeI64Add:
  1349  		c.emit(
  1350  			&OperationAdd{Type: UnsignedTypeI64},
  1351  		)
  1352  	case wasm.OpcodeI64Sub:
  1353  		c.emit(
  1354  			&OperationSub{Type: UnsignedTypeI64},
  1355  		)
  1356  	case wasm.OpcodeI64Mul:
  1357  		c.emit(
  1358  			&OperationMul{Type: UnsignedTypeI64},
  1359  		)
  1360  	case wasm.OpcodeI64DivS:
  1361  		c.emit(
  1362  			&OperationDiv{Type: SignedTypeInt64},
  1363  		)
  1364  	case wasm.OpcodeI64DivU:
  1365  		c.emit(
  1366  			&OperationDiv{Type: SignedTypeUint64},
  1367  		)
  1368  	case wasm.OpcodeI64RemS:
  1369  		c.emit(
  1370  			&OperationRem{Type: SignedInt64},
  1371  		)
  1372  	case wasm.OpcodeI64RemU:
  1373  		c.emit(
  1374  			&OperationRem{Type: SignedUint64},
  1375  		)
  1376  	case wasm.OpcodeI64And:
  1377  		c.emit(
  1378  			&OperationAnd{Type: UnsignedInt64},
  1379  		)
  1380  	case wasm.OpcodeI64Or:
  1381  		c.emit(
  1382  			&OperationOr{Type: UnsignedInt64},
  1383  		)
  1384  	case wasm.OpcodeI64Xor:
  1385  		c.emit(
  1386  			&OperationXor{Type: UnsignedInt64},
  1387  		)
  1388  	case wasm.OpcodeI64Shl:
  1389  		c.emit(
  1390  			&OperationShl{Type: UnsignedInt64},
  1391  		)
  1392  	case wasm.OpcodeI64ShrS:
  1393  		c.emit(
  1394  			&OperationShr{Type: SignedInt64},
  1395  		)
  1396  	case wasm.OpcodeI64ShrU:
  1397  		c.emit(
  1398  			&OperationShr{Type: SignedUint64},
  1399  		)
  1400  	case wasm.OpcodeI64Rotl:
  1401  		c.emit(
  1402  			&OperationRotl{Type: UnsignedInt64},
  1403  		)
  1404  	case wasm.OpcodeI64Rotr:
  1405  		c.emit(
  1406  			&OperationRotr{Type: UnsignedInt64},
  1407  		)
  1408  	case wasm.OpcodeF32Abs:
  1409  		c.emit(
  1410  			&OperationAbs{Type: Float32},
  1411  		)
  1412  	case wasm.OpcodeF32Neg:
  1413  		c.emit(
  1414  			&OperationNeg{Type: Float32},
  1415  		)
  1416  	case wasm.OpcodeF32Ceil:
  1417  		c.emit(
  1418  			&OperationCeil{Type: Float32},
  1419  		)
  1420  	case wasm.OpcodeF32Floor:
  1421  		c.emit(
  1422  			&OperationFloor{Type: Float32},
  1423  		)
  1424  	case wasm.OpcodeF32Trunc:
  1425  		c.emit(
  1426  			&OperationTrunc{Type: Float32},
  1427  		)
  1428  	case wasm.OpcodeF32Nearest:
  1429  		c.emit(
  1430  			&OperationNearest{Type: Float32},
  1431  		)
  1432  	case wasm.OpcodeF32Sqrt:
  1433  		c.emit(
  1434  			&OperationSqrt{Type: Float32},
  1435  		)
  1436  	case wasm.OpcodeF32Add:
  1437  		c.emit(
  1438  			&OperationAdd{Type: UnsignedTypeF32},
  1439  		)
  1440  	case wasm.OpcodeF32Sub:
  1441  		c.emit(
  1442  			&OperationSub{Type: UnsignedTypeF32},
  1443  		)
  1444  	case wasm.OpcodeF32Mul:
  1445  		c.emit(
  1446  			&OperationMul{Type: UnsignedTypeF32},
  1447  		)
  1448  	case wasm.OpcodeF32Div:
  1449  		c.emit(
  1450  			&OperationDiv{Type: SignedTypeFloat32},
  1451  		)
  1452  	case wasm.OpcodeF32Min:
  1453  		c.emit(
  1454  			&OperationMin{Type: Float32},
  1455  		)
  1456  	case wasm.OpcodeF32Max:
  1457  		c.emit(
  1458  			&OperationMax{Type: Float32},
  1459  		)
  1460  	case wasm.OpcodeF32Copysign:
  1461  		c.emit(
  1462  			&OperationCopysign{Type: Float32},
  1463  		)
  1464  	case wasm.OpcodeF64Abs:
  1465  		c.emit(
  1466  			&OperationAbs{Type: Float64},
  1467  		)
  1468  	case wasm.OpcodeF64Neg:
  1469  		c.emit(
  1470  			&OperationNeg{Type: Float64},
  1471  		)
  1472  	case wasm.OpcodeF64Ceil:
  1473  		c.emit(
  1474  			&OperationCeil{Type: Float64},
  1475  		)
  1476  	case wasm.OpcodeF64Floor:
  1477  		c.emit(
  1478  			&OperationFloor{Type: Float64},
  1479  		)
  1480  	case wasm.OpcodeF64Trunc:
  1481  		c.emit(
  1482  			&OperationTrunc{Type: Float64},
  1483  		)
  1484  	case wasm.OpcodeF64Nearest:
  1485  		c.emit(
  1486  			&OperationNearest{Type: Float64},
  1487  		)
  1488  	case wasm.OpcodeF64Sqrt:
  1489  		c.emit(
  1490  			&OperationSqrt{Type: Float64},
  1491  		)
  1492  	case wasm.OpcodeF64Add:
  1493  		c.emit(
  1494  			&OperationAdd{Type: UnsignedTypeF64},
  1495  		)
  1496  	case wasm.OpcodeF64Sub:
  1497  		c.emit(
  1498  			&OperationSub{Type: UnsignedTypeF64},
  1499  		)
  1500  	case wasm.OpcodeF64Mul:
  1501  		c.emit(
  1502  			&OperationMul{Type: UnsignedTypeF64},
  1503  		)
  1504  	case wasm.OpcodeF64Div:
  1505  		c.emit(
  1506  			&OperationDiv{Type: SignedTypeFloat64},
  1507  		)
  1508  	case wasm.OpcodeF64Min:
  1509  		c.emit(
  1510  			&OperationMin{Type: Float64},
  1511  		)
  1512  	case wasm.OpcodeF64Max:
  1513  		c.emit(
  1514  			&OperationMax{Type: Float64},
  1515  		)
  1516  	case wasm.OpcodeF64Copysign:
  1517  		c.emit(
  1518  			&OperationCopysign{Type: Float64},
  1519  		)
  1520  	case wasm.OpcodeI32WrapI64:
  1521  		c.emit(
  1522  			&OperationI32WrapFromI64{},
  1523  		)
  1524  	case wasm.OpcodeI32TruncF32S:
  1525  		c.emit(
  1526  			&OperationITruncFromF{InputType: Float32, OutputType: SignedInt32},
  1527  		)
  1528  	case wasm.OpcodeI32TruncF32U:
  1529  		c.emit(
  1530  			&OperationITruncFromF{InputType: Float32, OutputType: SignedUint32},
  1531  		)
  1532  	case wasm.OpcodeI32TruncF64S:
  1533  		c.emit(
  1534  			&OperationITruncFromF{InputType: Float64, OutputType: SignedInt32},
  1535  		)
  1536  	case wasm.OpcodeI32TruncF64U:
  1537  		c.emit(
  1538  			&OperationITruncFromF{InputType: Float64, OutputType: SignedUint32},
  1539  		)
  1540  	case wasm.OpcodeI64ExtendI32S:
  1541  		c.emit(
  1542  			&OperationExtend{Signed: true},
  1543  		)
  1544  	case wasm.OpcodeI64ExtendI32U:
  1545  		c.emit(
  1546  			&OperationExtend{Signed: false},
  1547  		)
  1548  	case wasm.OpcodeI64TruncF32S:
  1549  		c.emit(
  1550  			&OperationITruncFromF{InputType: Float32, OutputType: SignedInt64},
  1551  		)
  1552  	case wasm.OpcodeI64TruncF32U:
  1553  		c.emit(
  1554  			&OperationITruncFromF{InputType: Float32, OutputType: SignedUint64},
  1555  		)
  1556  	case wasm.OpcodeI64TruncF64S:
  1557  		c.emit(
  1558  			&OperationITruncFromF{InputType: Float64, OutputType: SignedInt64},
  1559  		)
  1560  	case wasm.OpcodeI64TruncF64U:
  1561  		c.emit(
  1562  			&OperationITruncFromF{InputType: Float64, OutputType: SignedUint64},
  1563  		)
  1564  	case wasm.OpcodeF32ConvertI32S:
  1565  		c.emit(
  1566  			&OperationFConvertFromI{InputType: SignedInt32, OutputType: Float32},
  1567  		)
  1568  	case wasm.OpcodeF32ConvertI32U:
  1569  		c.emit(
  1570  			&OperationFConvertFromI{InputType: SignedUint32, OutputType: Float32},
  1571  		)
  1572  	case wasm.OpcodeF32ConvertI64S:
  1573  		c.emit(
  1574  			&OperationFConvertFromI{InputType: SignedInt64, OutputType: Float32},
  1575  		)
  1576  	case wasm.OpcodeF32ConvertI64U:
  1577  		c.emit(
  1578  			&OperationFConvertFromI{InputType: SignedUint64, OutputType: Float32},
  1579  		)
  1580  	case wasm.OpcodeF32DemoteF64:
  1581  		c.emit(
  1582  			&OperationF32DemoteFromF64{},
  1583  		)
  1584  	case wasm.OpcodeF64ConvertI32S:
  1585  		c.emit(
  1586  			&OperationFConvertFromI{InputType: SignedInt32, OutputType: Float64},
  1587  		)
  1588  	case wasm.OpcodeF64ConvertI32U:
  1589  		c.emit(
  1590  			&OperationFConvertFromI{InputType: SignedUint32, OutputType: Float64},
  1591  		)
  1592  	case wasm.OpcodeF64ConvertI64S:
  1593  		c.emit(
  1594  			&OperationFConvertFromI{InputType: SignedInt64, OutputType: Float64},
  1595  		)
  1596  	case wasm.OpcodeF64ConvertI64U:
  1597  		c.emit(
  1598  			&OperationFConvertFromI{InputType: SignedUint64, OutputType: Float64},
  1599  		)
  1600  	case wasm.OpcodeF64PromoteF32:
  1601  		c.emit(
  1602  			&OperationF64PromoteFromF32{},
  1603  		)
  1604  	case wasm.OpcodeI32ReinterpretF32:
  1605  		c.emit(
  1606  			&OperationI32ReinterpretFromF32{},
  1607  		)
  1608  	case wasm.OpcodeI64ReinterpretF64:
  1609  		c.emit(
  1610  			&OperationI64ReinterpretFromF64{},
  1611  		)
  1612  	case wasm.OpcodeF32ReinterpretI32:
  1613  		c.emit(
  1614  			&OperationF32ReinterpretFromI32{},
  1615  		)
  1616  	case wasm.OpcodeF64ReinterpretI64:
  1617  		c.emit(
  1618  			&OperationF64ReinterpretFromI64{},
  1619  		)
  1620  	case wasm.OpcodeI32Extend8S:
  1621  		c.emit(
  1622  			&OperationSignExtend32From8{},
  1623  		)
  1624  	case wasm.OpcodeI32Extend16S:
  1625  		c.emit(
  1626  			&OperationSignExtend32From16{},
  1627  		)
  1628  	case wasm.OpcodeI64Extend8S:
  1629  		c.emit(
  1630  			&OperationSignExtend64From8{},
  1631  		)
  1632  	case wasm.OpcodeI64Extend16S:
  1633  		c.emit(
  1634  			&OperationSignExtend64From16{},
  1635  		)
  1636  	case wasm.OpcodeI64Extend32S:
  1637  		c.emit(
  1638  			&OperationSignExtend64From32{},
  1639  		)
  1640  	case wasm.OpcodeRefFunc:
  1641  		c.pc++
  1642  		index, num, err := leb128.LoadUint32(c.body[c.pc:])
  1643  		if err != nil {
  1644  			return fmt.Errorf("failed to read function index for ref.func: %v", err)
  1645  		}
  1646  		c.pc += num - 1
  1647  		c.emit(
  1648  			&OperationRefFunc{FunctionIndex: index},
  1649  		)
  1650  	case wasm.OpcodeRefNull:
  1651  		c.pc++ // Skip the type of reftype as every ref value is opaque pointer.
  1652  		c.emit(
  1653  			&OperationConstI64{Value: 0},
  1654  		)
  1655  	case wasm.OpcodeRefIsNull:
  1656  		// Simply compare the opaque pointer (i64) with zero.
  1657  		c.emit(
  1658  			&OperationEqz{Type: UnsignedInt64},
  1659  		)
  1660  	case wasm.OpcodeTableGet:
  1661  		c.pc++
  1662  		tableIndex, num, err := leb128.LoadUint32(c.body[c.pc:])
  1663  		if err != nil {
  1664  			return fmt.Errorf("failed to read function index for table.get: %v", err)
  1665  		}
  1666  		c.pc += num - 1
  1667  		c.emit(
  1668  			&OperationTableGet{TableIndex: tableIndex},
  1669  		)
  1670  	case wasm.OpcodeTableSet:
  1671  		c.pc++
  1672  		tableIndex, num, err := leb128.LoadUint32(c.body[c.pc:])
  1673  		if err != nil {
  1674  			return fmt.Errorf("failed to read function index for table.set: %v", err)
  1675  		}
  1676  		c.pc += num - 1
  1677  		c.emit(
  1678  			&OperationTableSet{TableIndex: tableIndex},
  1679  		)
  1680  	case wasm.OpcodeMiscPrefix:
  1681  		c.pc++
  1682  		// A misc opcode is encoded as an unsigned variable 32-bit integer.
  1683  		miscOp, num, err := leb128.LoadUint32(c.body[c.pc:])
  1684  		if err != nil {
  1685  			return fmt.Errorf("failed to read misc opcode: %v", err)
  1686  		}
  1687  		c.pc += num - 1
  1688  		switch byte(miscOp) {
  1689  		case wasm.OpcodeMiscI32TruncSatF32S:
  1690  			c.emit(
  1691  				&OperationITruncFromF{InputType: Float32, OutputType: SignedInt32, NonTrapping: true},
  1692  			)
  1693  		case wasm.OpcodeMiscI32TruncSatF32U:
  1694  			c.emit(
  1695  				&OperationITruncFromF{InputType: Float32, OutputType: SignedUint32, NonTrapping: true},
  1696  			)
  1697  		case wasm.OpcodeMiscI32TruncSatF64S:
  1698  			c.emit(
  1699  				&OperationITruncFromF{InputType: Float64, OutputType: SignedInt32, NonTrapping: true},
  1700  			)
  1701  		case wasm.OpcodeMiscI32TruncSatF64U:
  1702  			c.emit(
  1703  				&OperationITruncFromF{InputType: Float64, OutputType: SignedUint32, NonTrapping: true},
  1704  			)
  1705  		case wasm.OpcodeMiscI64TruncSatF32S:
  1706  			c.emit(
  1707  				&OperationITruncFromF{InputType: Float32, OutputType: SignedInt64, NonTrapping: true},
  1708  			)
  1709  		case wasm.OpcodeMiscI64TruncSatF32U:
  1710  			c.emit(
  1711  				&OperationITruncFromF{InputType: Float32, OutputType: SignedUint64, NonTrapping: true},
  1712  			)
  1713  		case wasm.OpcodeMiscI64TruncSatF64S:
  1714  			c.emit(
  1715  				&OperationITruncFromF{InputType: Float64, OutputType: SignedInt64, NonTrapping: true},
  1716  			)
  1717  		case wasm.OpcodeMiscI64TruncSatF64U:
  1718  			c.emit(
  1719  				&OperationITruncFromF{InputType: Float64, OutputType: SignedUint64, NonTrapping: true},
  1720  			)
  1721  		case wasm.OpcodeMiscMemoryInit:
  1722  			c.result.UsesMemory = true
  1723  			dataIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1724  			if err != nil {
  1725  				return fmt.Errorf("reading i32.const value: %v", err)
  1726  			}
  1727  			c.pc += num + 1 // +1 to skip the memory index which is fixed to zero.
  1728  			c.emit(
  1729  				&OperationMemoryInit{DataIndex: dataIndex},
  1730  			)
  1731  		case wasm.OpcodeMiscDataDrop:
  1732  			dataIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1733  			if err != nil {
  1734  				return fmt.Errorf("reading i32.const value: %v", err)
  1735  			}
  1736  			c.pc += num
  1737  			c.emit(
  1738  				&OperationDataDrop{DataIndex: dataIndex},
  1739  			)
  1740  		case wasm.OpcodeMiscMemoryCopy:
  1741  			c.result.UsesMemory = true
  1742  			c.pc += 2 // +2 to skip two memory indexes which are fixed to zero.
  1743  			c.emit(
  1744  				&OperationMemoryCopy{},
  1745  			)
  1746  		case wasm.OpcodeMiscMemoryFill:
  1747  			c.result.UsesMemory = true
  1748  			c.pc += 1 // +1 to skip the memory index which is fixed to zero.
  1749  			c.emit(
  1750  				&OperationMemoryFill{},
  1751  			)
  1752  		case wasm.OpcodeMiscTableInit:
  1753  			elemIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1754  			if err != nil {
  1755  				return fmt.Errorf("reading i32.const value: %v", err)
  1756  			}
  1757  			c.pc += num
  1758  			// Read table index which is fixed to zero currently.
  1759  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1760  			if err != nil {
  1761  				return fmt.Errorf("reading i32.const value: %v", err)
  1762  			}
  1763  			c.pc += num
  1764  			c.emit(
  1765  				&OperationTableInit{ElemIndex: elemIndex, TableIndex: tableIndex},
  1766  			)
  1767  		case wasm.OpcodeMiscElemDrop:
  1768  			elemIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1769  			if err != nil {
  1770  				return fmt.Errorf("reading i32.const value: %v", err)
  1771  			}
  1772  			c.pc += num
  1773  			c.emit(
  1774  				&OperationElemDrop{ElemIndex: elemIndex},
  1775  			)
  1776  		case wasm.OpcodeMiscTableCopy:
  1777  			// Read the source table inde.g.
  1778  			dst, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1779  			if err != nil {
  1780  				return fmt.Errorf("reading i32.const value: %v", err)
  1781  			}
  1782  			c.pc += num
  1783  			// Read the destination table inde.g.
  1784  			src, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1785  			if err != nil {
  1786  				return fmt.Errorf("reading i32.const value: %v", err)
  1787  			}
  1788  			c.pc += num
  1789  			c.emit(
  1790  				&OperationTableCopy{SrcTableIndex: src, DstTableIndex: dst},
  1791  			)
  1792  		case wasm.OpcodeMiscTableGrow:
  1793  			// Read the source table inde.g.
  1794  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1795  			if err != nil {
  1796  				return fmt.Errorf("reading i32.const value: %v", err)
  1797  			}
  1798  			c.pc += num
  1799  			c.emit(
  1800  				&OperationTableGrow{TableIndex: tableIndex},
  1801  			)
  1802  		case wasm.OpcodeMiscTableSize:
  1803  			// Read the source table inde.g.
  1804  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1805  			if err != nil {
  1806  				return fmt.Errorf("reading i32.const value: %v", err)
  1807  			}
  1808  			c.pc += num
  1809  			c.emit(
  1810  				&OperationTableSize{TableIndex: tableIndex},
  1811  			)
  1812  		case wasm.OpcodeMiscTableFill:
  1813  			// Read the source table index.
  1814  			tableIndex, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  1815  			if err != nil {
  1816  				return fmt.Errorf("reading i32.const value: %v", err)
  1817  			}
  1818  			c.pc += num
  1819  			c.emit(
  1820  				&OperationTableFill{TableIndex: tableIndex},
  1821  			)
  1822  		default:
  1823  			return fmt.Errorf("unsupported misc instruction in wazeroir: 0x%x", op)
  1824  		}
  1825  	case wasm.OpcodeVecPrefix:
  1826  		c.pc++
  1827  		switch vecOp := c.body[c.pc]; vecOp {
  1828  		case wasm.OpcodeVecV128Const:
  1829  			c.pc++
  1830  			lo := binary.LittleEndian.Uint64(c.body[c.pc : c.pc+8])
  1831  			c.pc += 8
  1832  			hi := binary.LittleEndian.Uint64(c.body[c.pc : c.pc+8])
  1833  			c.emit(
  1834  				&OperationV128Const{Lo: lo, Hi: hi},
  1835  			)
  1836  			c.pc += 7
  1837  		case wasm.OpcodeVecV128Load:
  1838  			arg, err := c.readMemoryArg(wasm.OpcodeI32LoadName)
  1839  			if err != nil {
  1840  				return err
  1841  			}
  1842  			c.emit(
  1843  				&OperationV128Load{Type: V128LoadType128, Arg: arg},
  1844  			)
  1845  		case wasm.OpcodeVecV128Load8x8s:
  1846  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8x8SName)
  1847  			if err != nil {
  1848  				return err
  1849  			}
  1850  			c.emit(
  1851  				&OperationV128Load{Type: V128LoadType8x8s, Arg: arg},
  1852  			)
  1853  		case wasm.OpcodeVecV128Load8x8u:
  1854  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8x8UName)
  1855  			if err != nil {
  1856  				return err
  1857  			}
  1858  			c.emit(
  1859  				&OperationV128Load{Type: V128LoadType8x8u, Arg: arg},
  1860  			)
  1861  		case wasm.OpcodeVecV128Load16x4s:
  1862  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16x4SName)
  1863  			if err != nil {
  1864  				return err
  1865  			}
  1866  			c.emit(
  1867  				&OperationV128Load{Type: V128LoadType16x4s, Arg: arg},
  1868  			)
  1869  		case wasm.OpcodeVecV128Load16x4u:
  1870  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16x4UName)
  1871  			if err != nil {
  1872  				return err
  1873  			}
  1874  			c.emit(
  1875  				&OperationV128Load{Type: V128LoadType16x4u, Arg: arg},
  1876  			)
  1877  		case wasm.OpcodeVecV128Load32x2s:
  1878  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32x2SName)
  1879  			if err != nil {
  1880  				return err
  1881  			}
  1882  			c.emit(
  1883  				&OperationV128Load{Type: V128LoadType32x2s, Arg: arg},
  1884  			)
  1885  		case wasm.OpcodeVecV128Load32x2u:
  1886  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32x2UName)
  1887  			if err != nil {
  1888  				return err
  1889  			}
  1890  			c.emit(
  1891  				&OperationV128Load{Type: V128LoadType32x2u, Arg: arg},
  1892  			)
  1893  		case wasm.OpcodeVecV128Load8Splat:
  1894  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8SplatName)
  1895  			if err != nil {
  1896  				return err
  1897  			}
  1898  			c.emit(
  1899  				&OperationV128Load{Type: V128LoadType8Splat, Arg: arg},
  1900  			)
  1901  		case wasm.OpcodeVecV128Load16Splat:
  1902  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16SplatName)
  1903  			if err != nil {
  1904  				return err
  1905  			}
  1906  			c.emit(
  1907  				&OperationV128Load{Type: V128LoadType16Splat, Arg: arg},
  1908  			)
  1909  		case wasm.OpcodeVecV128Load32Splat:
  1910  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32SplatName)
  1911  			if err != nil {
  1912  				return err
  1913  			}
  1914  			c.emit(
  1915  				&OperationV128Load{Type: V128LoadType32Splat, Arg: arg},
  1916  			)
  1917  		case wasm.OpcodeVecV128Load64Splat:
  1918  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load64SplatName)
  1919  			if err != nil {
  1920  				return err
  1921  			}
  1922  			c.emit(
  1923  				&OperationV128Load{Type: V128LoadType64Splat, Arg: arg},
  1924  			)
  1925  		case wasm.OpcodeVecV128Load32zero:
  1926  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32zeroName)
  1927  			if err != nil {
  1928  				return err
  1929  			}
  1930  			c.emit(
  1931  				&OperationV128Load{Type: V128LoadType32zero, Arg: arg},
  1932  			)
  1933  		case wasm.OpcodeVecV128Load64zero:
  1934  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load64zeroName)
  1935  			if err != nil {
  1936  				return err
  1937  			}
  1938  			c.emit(
  1939  				&OperationV128Load{Type: V128LoadType64zero, Arg: arg},
  1940  			)
  1941  		case wasm.OpcodeVecV128Load8Lane:
  1942  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load8LaneName)
  1943  			if err != nil {
  1944  				return err
  1945  			}
  1946  			c.pc++
  1947  			laneIndex := c.body[c.pc]
  1948  			c.emit(
  1949  				&OperationV128LoadLane{LaneIndex: laneIndex, LaneSize: 8, Arg: arg},
  1950  			)
  1951  		case wasm.OpcodeVecV128Load16Lane:
  1952  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load16LaneName)
  1953  			if err != nil {
  1954  				return err
  1955  			}
  1956  			c.pc++
  1957  			laneIndex := c.body[c.pc]
  1958  			c.emit(
  1959  				&OperationV128LoadLane{LaneIndex: laneIndex, LaneSize: 16, Arg: arg},
  1960  			)
  1961  		case wasm.OpcodeVecV128Load32Lane:
  1962  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load32LaneName)
  1963  			if err != nil {
  1964  				return err
  1965  			}
  1966  			c.pc++
  1967  			laneIndex := c.body[c.pc]
  1968  			c.emit(
  1969  				&OperationV128LoadLane{LaneIndex: laneIndex, LaneSize: 32, Arg: arg},
  1970  			)
  1971  		case wasm.OpcodeVecV128Load64Lane:
  1972  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Load64LaneName)
  1973  			if err != nil {
  1974  				return err
  1975  			}
  1976  			c.pc++
  1977  			laneIndex := c.body[c.pc]
  1978  			c.emit(
  1979  				&OperationV128LoadLane{LaneIndex: laneIndex, LaneSize: 64, Arg: arg},
  1980  			)
  1981  		case wasm.OpcodeVecV128Store:
  1982  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128StoreName)
  1983  			if err != nil {
  1984  				return err
  1985  			}
  1986  			c.emit(
  1987  				&OperationV128Store{Arg: arg},
  1988  			)
  1989  		case wasm.OpcodeVecV128Store8Lane:
  1990  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store8LaneName)
  1991  			if err != nil {
  1992  				return err
  1993  			}
  1994  			c.pc++
  1995  			laneIndex := c.body[c.pc]
  1996  			c.emit(
  1997  				&OperationV128StoreLane{LaneIndex: laneIndex, LaneSize: 8, Arg: arg},
  1998  			)
  1999  		case wasm.OpcodeVecV128Store16Lane:
  2000  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store16LaneName)
  2001  			if err != nil {
  2002  				return err
  2003  			}
  2004  			c.pc++
  2005  			laneIndex := c.body[c.pc]
  2006  			c.emit(
  2007  				&OperationV128StoreLane{LaneIndex: laneIndex, LaneSize: 16, Arg: arg},
  2008  			)
  2009  		case wasm.OpcodeVecV128Store32Lane:
  2010  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store32LaneName)
  2011  			if err != nil {
  2012  				return err
  2013  			}
  2014  			c.pc++
  2015  			laneIndex := c.body[c.pc]
  2016  			c.emit(
  2017  				&OperationV128StoreLane{LaneIndex: laneIndex, LaneSize: 32, Arg: arg},
  2018  			)
  2019  		case wasm.OpcodeVecV128Store64Lane:
  2020  			arg, err := c.readMemoryArg(wasm.OpcodeVecV128Store64LaneName)
  2021  			if err != nil {
  2022  				return err
  2023  			}
  2024  			c.pc++
  2025  			laneIndex := c.body[c.pc]
  2026  			c.emit(
  2027  				&OperationV128StoreLane{LaneIndex: laneIndex, LaneSize: 64, Arg: arg},
  2028  			)
  2029  		case wasm.OpcodeVecI8x16ExtractLaneS:
  2030  			c.pc++
  2031  			laneIndex := c.body[c.pc]
  2032  			c.emit(
  2033  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeI8x16, Signed: true},
  2034  			)
  2035  		case wasm.OpcodeVecI8x16ExtractLaneU:
  2036  			c.pc++
  2037  			laneIndex := c.body[c.pc]
  2038  			c.emit(
  2039  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeI8x16, Signed: false},
  2040  			)
  2041  		case wasm.OpcodeVecI16x8ExtractLaneS:
  2042  			c.pc++
  2043  			laneIndex := c.body[c.pc]
  2044  			c.emit(
  2045  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeI16x8, Signed: true},
  2046  			)
  2047  		case wasm.OpcodeVecI16x8ExtractLaneU:
  2048  			c.pc++
  2049  			laneIndex := c.body[c.pc]
  2050  			c.emit(
  2051  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeI16x8, Signed: false},
  2052  			)
  2053  		case wasm.OpcodeVecI32x4ExtractLane:
  2054  			c.pc++
  2055  			laneIndex := c.body[c.pc]
  2056  			c.emit(
  2057  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeI32x4},
  2058  			)
  2059  		case wasm.OpcodeVecI64x2ExtractLane:
  2060  			c.pc++
  2061  			laneIndex := c.body[c.pc]
  2062  			c.emit(
  2063  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeI64x2},
  2064  			)
  2065  		case wasm.OpcodeVecF32x4ExtractLane:
  2066  			c.pc++
  2067  			laneIndex := c.body[c.pc]
  2068  			c.emit(
  2069  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeF32x4},
  2070  			)
  2071  		case wasm.OpcodeVecF64x2ExtractLane:
  2072  			c.pc++
  2073  			laneIndex := c.body[c.pc]
  2074  			c.emit(
  2075  				&OperationV128ExtractLane{LaneIndex: laneIndex, Shape: ShapeF64x2},
  2076  			)
  2077  		case wasm.OpcodeVecI8x16ReplaceLane:
  2078  			c.pc++
  2079  			laneIndex := c.body[c.pc]
  2080  			c.emit(
  2081  				&OperationV128ReplaceLane{LaneIndex: laneIndex, Shape: ShapeI8x16},
  2082  			)
  2083  		case wasm.OpcodeVecI16x8ReplaceLane:
  2084  			c.pc++
  2085  			laneIndex := c.body[c.pc]
  2086  			c.emit(
  2087  				&OperationV128ReplaceLane{LaneIndex: laneIndex, Shape: ShapeI16x8},
  2088  			)
  2089  		case wasm.OpcodeVecI32x4ReplaceLane:
  2090  			c.pc++
  2091  			laneIndex := c.body[c.pc]
  2092  			c.emit(
  2093  				&OperationV128ReplaceLane{LaneIndex: laneIndex, Shape: ShapeI32x4},
  2094  			)
  2095  		case wasm.OpcodeVecI64x2ReplaceLane:
  2096  			c.pc++
  2097  			laneIndex := c.body[c.pc]
  2098  			c.emit(
  2099  				&OperationV128ReplaceLane{LaneIndex: laneIndex, Shape: ShapeI64x2},
  2100  			)
  2101  		case wasm.OpcodeVecF32x4ReplaceLane:
  2102  			c.pc++
  2103  			laneIndex := c.body[c.pc]
  2104  			c.emit(
  2105  				&OperationV128ReplaceLane{LaneIndex: laneIndex, Shape: ShapeF32x4},
  2106  			)
  2107  		case wasm.OpcodeVecF64x2ReplaceLane:
  2108  			c.pc++
  2109  			laneIndex := c.body[c.pc]
  2110  			c.emit(
  2111  				&OperationV128ReplaceLane{LaneIndex: laneIndex, Shape: ShapeF64x2},
  2112  			)
  2113  		case wasm.OpcodeVecI8x16Splat:
  2114  			c.emit(
  2115  				&OperationV128Splat{Shape: ShapeI8x16},
  2116  			)
  2117  		case wasm.OpcodeVecI16x8Splat:
  2118  			c.emit(
  2119  				&OperationV128Splat{Shape: ShapeI16x8},
  2120  			)
  2121  		case wasm.OpcodeVecI32x4Splat:
  2122  			c.emit(
  2123  				&OperationV128Splat{Shape: ShapeI32x4},
  2124  			)
  2125  		case wasm.OpcodeVecI64x2Splat:
  2126  			c.emit(
  2127  				&OperationV128Splat{Shape: ShapeI64x2},
  2128  			)
  2129  		case wasm.OpcodeVecF32x4Splat:
  2130  			c.emit(
  2131  				&OperationV128Splat{Shape: ShapeF32x4},
  2132  			)
  2133  		case wasm.OpcodeVecF64x2Splat:
  2134  			c.emit(
  2135  				&OperationV128Splat{Shape: ShapeF64x2},
  2136  			)
  2137  		case wasm.OpcodeVecI8x16Swizzle:
  2138  			c.emit(
  2139  				&OperationV128Swizzle{},
  2140  			)
  2141  		case wasm.OpcodeVecV128i8x16Shuffle:
  2142  			c.pc++
  2143  			op := &OperationV128Shuffle{}
  2144  			copy(op.Lanes[:], c.body[c.pc:c.pc+16])
  2145  			c.emit(op)
  2146  			c.pc += 15
  2147  		case wasm.OpcodeVecV128AnyTrue:
  2148  			c.emit(
  2149  				&OperationV128AnyTrue{},
  2150  			)
  2151  		case wasm.OpcodeVecI8x16AllTrue:
  2152  			c.emit(
  2153  				&OperationV128AllTrue{Shape: ShapeI8x16},
  2154  			)
  2155  		case wasm.OpcodeVecI16x8AllTrue:
  2156  			c.emit(
  2157  				&OperationV128AllTrue{Shape: ShapeI16x8},
  2158  			)
  2159  		case wasm.OpcodeVecI32x4AllTrue:
  2160  			c.emit(
  2161  				&OperationV128AllTrue{Shape: ShapeI32x4},
  2162  			)
  2163  		case wasm.OpcodeVecI64x2AllTrue:
  2164  			c.emit(
  2165  				&OperationV128AllTrue{Shape: ShapeI64x2},
  2166  			)
  2167  		case wasm.OpcodeVecI8x16BitMask:
  2168  			c.emit(
  2169  				&OperationV128BitMask{Shape: ShapeI8x16},
  2170  			)
  2171  		case wasm.OpcodeVecI16x8BitMask:
  2172  			c.emit(
  2173  				&OperationV128BitMask{Shape: ShapeI16x8},
  2174  			)
  2175  		case wasm.OpcodeVecI32x4BitMask:
  2176  			c.emit(
  2177  				&OperationV128BitMask{Shape: ShapeI32x4},
  2178  			)
  2179  		case wasm.OpcodeVecI64x2BitMask:
  2180  			c.emit(
  2181  				&OperationV128BitMask{Shape: ShapeI64x2},
  2182  			)
  2183  		case wasm.OpcodeVecV128And:
  2184  			c.emit(
  2185  				&OperationV128And{},
  2186  			)
  2187  		case wasm.OpcodeVecV128Not:
  2188  			c.emit(
  2189  				&OperationV128Not{},
  2190  			)
  2191  		case wasm.OpcodeVecV128Or:
  2192  			c.emit(
  2193  				&OperationV128Or{},
  2194  			)
  2195  		case wasm.OpcodeVecV128Xor:
  2196  			c.emit(
  2197  				&OperationV128Xor{},
  2198  			)
  2199  		case wasm.OpcodeVecV128Bitselect:
  2200  			c.emit(
  2201  				&OperationV128Bitselect{},
  2202  			)
  2203  		case wasm.OpcodeVecV128AndNot:
  2204  			c.emit(
  2205  				&OperationV128AndNot{},
  2206  			)
  2207  		case wasm.OpcodeVecI8x16Shl:
  2208  			c.emit(
  2209  				&OperationV128Shl{Shape: ShapeI8x16},
  2210  			)
  2211  		case wasm.OpcodeVecI8x16ShrS:
  2212  			c.emit(
  2213  				&OperationV128Shr{Shape: ShapeI8x16, Signed: true},
  2214  			)
  2215  		case wasm.OpcodeVecI8x16ShrU:
  2216  			c.emit(
  2217  				&OperationV128Shr{Shape: ShapeI8x16, Signed: false},
  2218  			)
  2219  		case wasm.OpcodeVecI16x8Shl:
  2220  			c.emit(
  2221  				&OperationV128Shl{Shape: ShapeI16x8},
  2222  			)
  2223  		case wasm.OpcodeVecI16x8ShrS:
  2224  			c.emit(
  2225  				&OperationV128Shr{Shape: ShapeI16x8, Signed: true},
  2226  			)
  2227  		case wasm.OpcodeVecI16x8ShrU:
  2228  			c.emit(
  2229  				&OperationV128Shr{Shape: ShapeI16x8, Signed: false},
  2230  			)
  2231  		case wasm.OpcodeVecI32x4Shl:
  2232  			c.emit(
  2233  				&OperationV128Shl{Shape: ShapeI32x4},
  2234  			)
  2235  		case wasm.OpcodeVecI32x4ShrS:
  2236  			c.emit(
  2237  				&OperationV128Shr{Shape: ShapeI32x4, Signed: true},
  2238  			)
  2239  		case wasm.OpcodeVecI32x4ShrU:
  2240  			c.emit(
  2241  				&OperationV128Shr{Shape: ShapeI32x4, Signed: false},
  2242  			)
  2243  		case wasm.OpcodeVecI64x2Shl:
  2244  			c.emit(
  2245  				&OperationV128Shl{Shape: ShapeI64x2},
  2246  			)
  2247  		case wasm.OpcodeVecI64x2ShrS:
  2248  			c.emit(
  2249  				&OperationV128Shr{Shape: ShapeI64x2, Signed: true},
  2250  			)
  2251  		case wasm.OpcodeVecI64x2ShrU:
  2252  			c.emit(
  2253  				&OperationV128Shr{Shape: ShapeI64x2, Signed: false},
  2254  			)
  2255  		case wasm.OpcodeVecI8x16Eq:
  2256  			c.emit(
  2257  				&OperationV128Cmp{Type: V128CmpTypeI8x16Eq},
  2258  			)
  2259  		case wasm.OpcodeVecI8x16Ne:
  2260  			c.emit(
  2261  				&OperationV128Cmp{Type: V128CmpTypeI8x16Ne},
  2262  			)
  2263  		case wasm.OpcodeVecI8x16LtS:
  2264  			c.emit(
  2265  				&OperationV128Cmp{Type: V128CmpTypeI8x16LtS},
  2266  			)
  2267  		case wasm.OpcodeVecI8x16LtU:
  2268  			c.emit(
  2269  				&OperationV128Cmp{Type: V128CmpTypeI8x16LtU},
  2270  			)
  2271  		case wasm.OpcodeVecI8x16GtS:
  2272  			c.emit(
  2273  				&OperationV128Cmp{Type: V128CmpTypeI8x16GtS},
  2274  			)
  2275  		case wasm.OpcodeVecI8x16GtU:
  2276  			c.emit(
  2277  				&OperationV128Cmp{Type: V128CmpTypeI8x16GtU},
  2278  			)
  2279  		case wasm.OpcodeVecI8x16LeS:
  2280  			c.emit(
  2281  				&OperationV128Cmp{Type: V128CmpTypeI8x16LeS},
  2282  			)
  2283  		case wasm.OpcodeVecI8x16LeU:
  2284  			c.emit(
  2285  				&OperationV128Cmp{Type: V128CmpTypeI8x16LeU},
  2286  			)
  2287  		case wasm.OpcodeVecI8x16GeS:
  2288  			c.emit(
  2289  				&OperationV128Cmp{Type: V128CmpTypeI8x16GeS},
  2290  			)
  2291  		case wasm.OpcodeVecI8x16GeU:
  2292  			c.emit(
  2293  				&OperationV128Cmp{Type: V128CmpTypeI8x16GeU},
  2294  			)
  2295  		case wasm.OpcodeVecI16x8Eq:
  2296  			c.emit(
  2297  				&OperationV128Cmp{Type: V128CmpTypeI16x8Eq},
  2298  			)
  2299  		case wasm.OpcodeVecI16x8Ne:
  2300  			c.emit(
  2301  				&OperationV128Cmp{Type: V128CmpTypeI16x8Ne},
  2302  			)
  2303  		case wasm.OpcodeVecI16x8LtS:
  2304  			c.emit(
  2305  				&OperationV128Cmp{Type: V128CmpTypeI16x8LtS},
  2306  			)
  2307  		case wasm.OpcodeVecI16x8LtU:
  2308  			c.emit(
  2309  				&OperationV128Cmp{Type: V128CmpTypeI16x8LtU},
  2310  			)
  2311  		case wasm.OpcodeVecI16x8GtS:
  2312  			c.emit(
  2313  				&OperationV128Cmp{Type: V128CmpTypeI16x8GtS},
  2314  			)
  2315  		case wasm.OpcodeVecI16x8GtU:
  2316  			c.emit(
  2317  				&OperationV128Cmp{Type: V128CmpTypeI16x8GtU},
  2318  			)
  2319  		case wasm.OpcodeVecI16x8LeS:
  2320  			c.emit(
  2321  				&OperationV128Cmp{Type: V128CmpTypeI16x8LeS},
  2322  			)
  2323  		case wasm.OpcodeVecI16x8LeU:
  2324  			c.emit(
  2325  				&OperationV128Cmp{Type: V128CmpTypeI16x8LeU},
  2326  			)
  2327  		case wasm.OpcodeVecI16x8GeS:
  2328  			c.emit(
  2329  				&OperationV128Cmp{Type: V128CmpTypeI16x8GeS},
  2330  			)
  2331  		case wasm.OpcodeVecI16x8GeU:
  2332  			c.emit(
  2333  				&OperationV128Cmp{Type: V128CmpTypeI16x8GeU},
  2334  			)
  2335  		case wasm.OpcodeVecI32x4Eq:
  2336  			c.emit(
  2337  				&OperationV128Cmp{Type: V128CmpTypeI32x4Eq},
  2338  			)
  2339  		case wasm.OpcodeVecI32x4Ne:
  2340  			c.emit(
  2341  				&OperationV128Cmp{Type: V128CmpTypeI32x4Ne},
  2342  			)
  2343  		case wasm.OpcodeVecI32x4LtS:
  2344  			c.emit(
  2345  				&OperationV128Cmp{Type: V128CmpTypeI32x4LtS},
  2346  			)
  2347  		case wasm.OpcodeVecI32x4LtU:
  2348  			c.emit(
  2349  				&OperationV128Cmp{Type: V128CmpTypeI32x4LtU},
  2350  			)
  2351  		case wasm.OpcodeVecI32x4GtS:
  2352  			c.emit(
  2353  				&OperationV128Cmp{Type: V128CmpTypeI32x4GtS},
  2354  			)
  2355  		case wasm.OpcodeVecI32x4GtU:
  2356  			c.emit(
  2357  				&OperationV128Cmp{Type: V128CmpTypeI32x4GtU},
  2358  			)
  2359  		case wasm.OpcodeVecI32x4LeS:
  2360  			c.emit(
  2361  				&OperationV128Cmp{Type: V128CmpTypeI32x4LeS},
  2362  			)
  2363  		case wasm.OpcodeVecI32x4LeU:
  2364  			c.emit(
  2365  				&OperationV128Cmp{Type: V128CmpTypeI32x4LeU},
  2366  			)
  2367  		case wasm.OpcodeVecI32x4GeS:
  2368  			c.emit(
  2369  				&OperationV128Cmp{Type: V128CmpTypeI32x4GeS},
  2370  			)
  2371  		case wasm.OpcodeVecI32x4GeU:
  2372  			c.emit(
  2373  				&OperationV128Cmp{Type: V128CmpTypeI32x4GeU},
  2374  			)
  2375  		case wasm.OpcodeVecI64x2Eq:
  2376  			c.emit(
  2377  				&OperationV128Cmp{Type: V128CmpTypeI64x2Eq},
  2378  			)
  2379  		case wasm.OpcodeVecI64x2Ne:
  2380  			c.emit(
  2381  				&OperationV128Cmp{Type: V128CmpTypeI64x2Ne},
  2382  			)
  2383  		case wasm.OpcodeVecI64x2LtS:
  2384  			c.emit(
  2385  				&OperationV128Cmp{Type: V128CmpTypeI64x2LtS},
  2386  			)
  2387  		case wasm.OpcodeVecI64x2GtS:
  2388  			c.emit(
  2389  				&OperationV128Cmp{Type: V128CmpTypeI64x2GtS},
  2390  			)
  2391  		case wasm.OpcodeVecI64x2LeS:
  2392  			c.emit(
  2393  				&OperationV128Cmp{Type: V128CmpTypeI64x2LeS},
  2394  			)
  2395  		case wasm.OpcodeVecI64x2GeS:
  2396  			c.emit(
  2397  				&OperationV128Cmp{Type: V128CmpTypeI64x2GeS},
  2398  			)
  2399  		case wasm.OpcodeVecF32x4Eq:
  2400  			c.emit(
  2401  				&OperationV128Cmp{Type: V128CmpTypeF32x4Eq},
  2402  			)
  2403  		case wasm.OpcodeVecF32x4Ne:
  2404  			c.emit(
  2405  				&OperationV128Cmp{Type: V128CmpTypeF32x4Ne},
  2406  			)
  2407  		case wasm.OpcodeVecF32x4Lt:
  2408  			c.emit(
  2409  				&OperationV128Cmp{Type: V128CmpTypeF32x4Lt},
  2410  			)
  2411  		case wasm.OpcodeVecF32x4Gt:
  2412  			c.emit(
  2413  				&OperationV128Cmp{Type: V128CmpTypeF32x4Gt},
  2414  			)
  2415  		case wasm.OpcodeVecF32x4Le:
  2416  			c.emit(
  2417  				&OperationV128Cmp{Type: V128CmpTypeF32x4Le},
  2418  			)
  2419  		case wasm.OpcodeVecF32x4Ge:
  2420  			c.emit(
  2421  				&OperationV128Cmp{Type: V128CmpTypeF32x4Ge},
  2422  			)
  2423  		case wasm.OpcodeVecF64x2Eq:
  2424  			c.emit(
  2425  				&OperationV128Cmp{Type: V128CmpTypeF64x2Eq},
  2426  			)
  2427  		case wasm.OpcodeVecF64x2Ne:
  2428  			c.emit(
  2429  				&OperationV128Cmp{Type: V128CmpTypeF64x2Ne},
  2430  			)
  2431  		case wasm.OpcodeVecF64x2Lt:
  2432  			c.emit(
  2433  				&OperationV128Cmp{Type: V128CmpTypeF64x2Lt},
  2434  			)
  2435  		case wasm.OpcodeVecF64x2Gt:
  2436  			c.emit(
  2437  				&OperationV128Cmp{Type: V128CmpTypeF64x2Gt},
  2438  			)
  2439  		case wasm.OpcodeVecF64x2Le:
  2440  			c.emit(
  2441  				&OperationV128Cmp{Type: V128CmpTypeF64x2Le},
  2442  			)
  2443  		case wasm.OpcodeVecF64x2Ge:
  2444  			c.emit(
  2445  				&OperationV128Cmp{Type: V128CmpTypeF64x2Ge},
  2446  			)
  2447  		case wasm.OpcodeVecI8x16Neg:
  2448  			c.emit(
  2449  				&OperationV128Neg{Shape: ShapeI8x16},
  2450  			)
  2451  		case wasm.OpcodeVecI16x8Neg:
  2452  			c.emit(
  2453  				&OperationV128Neg{Shape: ShapeI16x8},
  2454  			)
  2455  		case wasm.OpcodeVecI32x4Neg:
  2456  			c.emit(
  2457  				&OperationV128Neg{Shape: ShapeI32x4},
  2458  			)
  2459  		case wasm.OpcodeVecI64x2Neg:
  2460  			c.emit(
  2461  				&OperationV128Neg{Shape: ShapeI64x2},
  2462  			)
  2463  		case wasm.OpcodeVecF32x4Neg:
  2464  			c.emit(
  2465  				&OperationV128Neg{Shape: ShapeF32x4},
  2466  			)
  2467  		case wasm.OpcodeVecF64x2Neg:
  2468  			c.emit(
  2469  				&OperationV128Neg{Shape: ShapeF64x2},
  2470  			)
  2471  		case wasm.OpcodeVecI8x16Add:
  2472  			c.emit(
  2473  				&OperationV128Add{Shape: ShapeI8x16},
  2474  			)
  2475  		case wasm.OpcodeVecI16x8Add:
  2476  			c.emit(
  2477  				&OperationV128Add{Shape: ShapeI16x8},
  2478  			)
  2479  		case wasm.OpcodeVecI32x4Add:
  2480  			c.emit(
  2481  				&OperationV128Add{Shape: ShapeI32x4},
  2482  			)
  2483  		case wasm.OpcodeVecI64x2Add:
  2484  			c.emit(
  2485  				&OperationV128Add{Shape: ShapeI64x2},
  2486  			)
  2487  		case wasm.OpcodeVecF32x4Add:
  2488  			c.emit(
  2489  				&OperationV128Add{Shape: ShapeF32x4},
  2490  			)
  2491  		case wasm.OpcodeVecF64x2Add:
  2492  			c.emit(
  2493  				&OperationV128Add{Shape: ShapeF64x2},
  2494  			)
  2495  		case wasm.OpcodeVecI8x16Sub:
  2496  			c.emit(
  2497  				&OperationV128Sub{Shape: ShapeI8x16},
  2498  			)
  2499  		case wasm.OpcodeVecI16x8Sub:
  2500  			c.emit(
  2501  				&OperationV128Sub{Shape: ShapeI16x8},
  2502  			)
  2503  		case wasm.OpcodeVecI32x4Sub:
  2504  			c.emit(
  2505  				&OperationV128Sub{Shape: ShapeI32x4},
  2506  			)
  2507  		case wasm.OpcodeVecI64x2Sub:
  2508  			c.emit(
  2509  				&OperationV128Sub{Shape: ShapeI64x2},
  2510  			)
  2511  		case wasm.OpcodeVecF32x4Sub:
  2512  			c.emit(
  2513  				&OperationV128Sub{Shape: ShapeF32x4},
  2514  			)
  2515  		case wasm.OpcodeVecF64x2Sub:
  2516  			c.emit(
  2517  				&OperationV128Sub{Shape: ShapeF64x2},
  2518  			)
  2519  		case wasm.OpcodeVecI8x16AddSatS:
  2520  			c.emit(
  2521  				&OperationV128AddSat{Shape: ShapeI8x16, Signed: true},
  2522  			)
  2523  		case wasm.OpcodeVecI8x16AddSatU:
  2524  			c.emit(
  2525  				&OperationV128AddSat{Shape: ShapeI8x16, Signed: false},
  2526  			)
  2527  		case wasm.OpcodeVecI16x8AddSatS:
  2528  			c.emit(
  2529  				&OperationV128AddSat{Shape: ShapeI16x8, Signed: true},
  2530  			)
  2531  		case wasm.OpcodeVecI16x8AddSatU:
  2532  			c.emit(
  2533  				&OperationV128AddSat{Shape: ShapeI16x8, Signed: false},
  2534  			)
  2535  		case wasm.OpcodeVecI8x16SubSatS:
  2536  			c.emit(
  2537  				&OperationV128SubSat{Shape: ShapeI8x16, Signed: true},
  2538  			)
  2539  		case wasm.OpcodeVecI8x16SubSatU:
  2540  			c.emit(
  2541  				&OperationV128SubSat{Shape: ShapeI8x16, Signed: false},
  2542  			)
  2543  		case wasm.OpcodeVecI16x8SubSatS:
  2544  			c.emit(
  2545  				&OperationV128SubSat{Shape: ShapeI16x8, Signed: true},
  2546  			)
  2547  		case wasm.OpcodeVecI16x8SubSatU:
  2548  			c.emit(
  2549  				&OperationV128SubSat{Shape: ShapeI16x8, Signed: false},
  2550  			)
  2551  		case wasm.OpcodeVecI16x8Mul:
  2552  			c.emit(
  2553  				&OperationV128Mul{Shape: ShapeI16x8},
  2554  			)
  2555  		case wasm.OpcodeVecI32x4Mul:
  2556  			c.emit(
  2557  				&OperationV128Mul{Shape: ShapeI32x4},
  2558  			)
  2559  		case wasm.OpcodeVecI64x2Mul:
  2560  			c.emit(
  2561  				&OperationV128Mul{Shape: ShapeI64x2},
  2562  			)
  2563  		case wasm.OpcodeVecF32x4Mul:
  2564  			c.emit(
  2565  				&OperationV128Mul{Shape: ShapeF32x4},
  2566  			)
  2567  		case wasm.OpcodeVecF64x2Mul:
  2568  			c.emit(
  2569  				&OperationV128Mul{Shape: ShapeF64x2},
  2570  			)
  2571  		case wasm.OpcodeVecF32x4Sqrt:
  2572  			c.emit(
  2573  				&OperationV128Sqrt{Shape: ShapeF32x4},
  2574  			)
  2575  		case wasm.OpcodeVecF64x2Sqrt:
  2576  			c.emit(
  2577  				&OperationV128Sqrt{Shape: ShapeF64x2},
  2578  			)
  2579  		case wasm.OpcodeVecF32x4Div:
  2580  			c.emit(
  2581  				&OperationV128Div{Shape: ShapeF32x4},
  2582  			)
  2583  		case wasm.OpcodeVecF64x2Div:
  2584  			c.emit(
  2585  				&OperationV128Div{Shape: ShapeF64x2},
  2586  			)
  2587  		case wasm.OpcodeVecI8x16Abs:
  2588  			c.emit(
  2589  				&OperationV128Abs{Shape: ShapeI8x16},
  2590  			)
  2591  		case wasm.OpcodeVecI8x16Popcnt:
  2592  			c.emit(
  2593  				&OperationV128Popcnt{},
  2594  			)
  2595  		case wasm.OpcodeVecI16x8Abs:
  2596  			c.emit(
  2597  				&OperationV128Abs{Shape: ShapeI16x8},
  2598  			)
  2599  		case wasm.OpcodeVecI32x4Abs:
  2600  			c.emit(
  2601  				&OperationV128Abs{Shape: ShapeI32x4},
  2602  			)
  2603  		case wasm.OpcodeVecI64x2Abs:
  2604  			c.emit(
  2605  				&OperationV128Abs{Shape: ShapeI64x2},
  2606  			)
  2607  		case wasm.OpcodeVecF32x4Abs:
  2608  			c.emit(
  2609  				&OperationV128Abs{Shape: ShapeF32x4},
  2610  			)
  2611  		case wasm.OpcodeVecF64x2Abs:
  2612  			c.emit(
  2613  				&OperationV128Abs{Shape: ShapeF64x2},
  2614  			)
  2615  		case wasm.OpcodeVecI8x16MinS:
  2616  			c.emit(
  2617  				&OperationV128Min{Signed: true, Shape: ShapeI8x16},
  2618  			)
  2619  		case wasm.OpcodeVecI8x16MinU:
  2620  			c.emit(
  2621  				&OperationV128Min{Shape: ShapeI8x16},
  2622  			)
  2623  		case wasm.OpcodeVecI8x16MaxS:
  2624  			c.emit(
  2625  				&OperationV128Max{Shape: ShapeI8x16, Signed: true},
  2626  			)
  2627  		case wasm.OpcodeVecI8x16MaxU:
  2628  			c.emit(
  2629  				&OperationV128Max{Shape: ShapeI8x16},
  2630  			)
  2631  		case wasm.OpcodeVecI8x16AvgrU:
  2632  			c.emit(
  2633  				&OperationV128AvgrU{Shape: ShapeI8x16},
  2634  			)
  2635  		case wasm.OpcodeVecI16x8MinS:
  2636  			c.emit(
  2637  				&OperationV128Min{Signed: true, Shape: ShapeI16x8},
  2638  			)
  2639  		case wasm.OpcodeVecI16x8MinU:
  2640  			c.emit(
  2641  				&OperationV128Min{Shape: ShapeI16x8},
  2642  			)
  2643  		case wasm.OpcodeVecI16x8MaxS:
  2644  			c.emit(
  2645  				&OperationV128Max{Shape: ShapeI16x8, Signed: true},
  2646  			)
  2647  		case wasm.OpcodeVecI16x8MaxU:
  2648  			c.emit(
  2649  				&OperationV128Max{Shape: ShapeI16x8},
  2650  			)
  2651  		case wasm.OpcodeVecI16x8AvgrU:
  2652  			c.emit(
  2653  				&OperationV128AvgrU{Shape: ShapeI16x8},
  2654  			)
  2655  		case wasm.OpcodeVecI32x4MinS:
  2656  			c.emit(
  2657  				&OperationV128Min{Signed: true, Shape: ShapeI32x4},
  2658  			)
  2659  		case wasm.OpcodeVecI32x4MinU:
  2660  			c.emit(
  2661  				&OperationV128Min{Shape: ShapeI32x4},
  2662  			)
  2663  		case wasm.OpcodeVecI32x4MaxS:
  2664  			c.emit(
  2665  				&OperationV128Max{Shape: ShapeI32x4, Signed: true},
  2666  			)
  2667  		case wasm.OpcodeVecI32x4MaxU:
  2668  			c.emit(
  2669  				&OperationV128Max{Shape: ShapeI32x4},
  2670  			)
  2671  		case wasm.OpcodeVecF32x4Min:
  2672  			c.emit(
  2673  				&OperationV128Min{Shape: ShapeF32x4},
  2674  			)
  2675  		case wasm.OpcodeVecF32x4Max:
  2676  			c.emit(
  2677  				&OperationV128Max{Shape: ShapeF32x4},
  2678  			)
  2679  		case wasm.OpcodeVecF64x2Min:
  2680  			c.emit(
  2681  				&OperationV128Min{Shape: ShapeF64x2},
  2682  			)
  2683  		case wasm.OpcodeVecF64x2Max:
  2684  			c.emit(
  2685  				&OperationV128Max{Shape: ShapeF64x2},
  2686  			)
  2687  		case wasm.OpcodeVecF32x4Pmin:
  2688  			c.emit(
  2689  				&OperationV128Pmin{Shape: ShapeF32x4},
  2690  			)
  2691  		case wasm.OpcodeVecF32x4Pmax:
  2692  			c.emit(
  2693  				&OperationV128Pmax{Shape: ShapeF32x4},
  2694  			)
  2695  		case wasm.OpcodeVecF64x2Pmin:
  2696  			c.emit(
  2697  				&OperationV128Pmin{Shape: ShapeF64x2},
  2698  			)
  2699  		case wasm.OpcodeVecF64x2Pmax:
  2700  			c.emit(
  2701  				&OperationV128Pmax{Shape: ShapeF64x2},
  2702  			)
  2703  		case wasm.OpcodeVecF32x4Ceil:
  2704  			c.emit(
  2705  				&OperationV128Ceil{Shape: ShapeF32x4},
  2706  			)
  2707  		case wasm.OpcodeVecF32x4Floor:
  2708  			c.emit(
  2709  				&OperationV128Floor{Shape: ShapeF32x4},
  2710  			)
  2711  		case wasm.OpcodeVecF32x4Trunc:
  2712  			c.emit(
  2713  				&OperationV128Trunc{Shape: ShapeF32x4},
  2714  			)
  2715  		case wasm.OpcodeVecF32x4Nearest:
  2716  			c.emit(
  2717  				&OperationV128Nearest{Shape: ShapeF32x4},
  2718  			)
  2719  		case wasm.OpcodeVecF64x2Ceil:
  2720  			c.emit(
  2721  				&OperationV128Ceil{Shape: ShapeF64x2},
  2722  			)
  2723  		case wasm.OpcodeVecF64x2Floor:
  2724  			c.emit(
  2725  				&OperationV128Floor{Shape: ShapeF64x2},
  2726  			)
  2727  		case wasm.OpcodeVecF64x2Trunc:
  2728  			c.emit(
  2729  				&OperationV128Trunc{Shape: ShapeF64x2},
  2730  			)
  2731  		case wasm.OpcodeVecF64x2Nearest:
  2732  			c.emit(
  2733  				&OperationV128Nearest{Shape: ShapeF64x2},
  2734  			)
  2735  		case wasm.OpcodeVecI16x8ExtendLowI8x16S:
  2736  			c.emit(
  2737  				&OperationV128Extend{OriginShape: ShapeI8x16, Signed: true, UseLow: true},
  2738  			)
  2739  		case wasm.OpcodeVecI16x8ExtendHighI8x16S:
  2740  			c.emit(
  2741  				&OperationV128Extend{OriginShape: ShapeI8x16, Signed: true, UseLow: false},
  2742  			)
  2743  		case wasm.OpcodeVecI16x8ExtendLowI8x16U:
  2744  			c.emit(
  2745  				&OperationV128Extend{OriginShape: ShapeI8x16, Signed: false, UseLow: true},
  2746  			)
  2747  		case wasm.OpcodeVecI16x8ExtendHighI8x16U:
  2748  			c.emit(
  2749  				&OperationV128Extend{OriginShape: ShapeI8x16, Signed: false, UseLow: false},
  2750  			)
  2751  		case wasm.OpcodeVecI32x4ExtendLowI16x8S:
  2752  			c.emit(
  2753  				&OperationV128Extend{OriginShape: ShapeI16x8, Signed: true, UseLow: true},
  2754  			)
  2755  		case wasm.OpcodeVecI32x4ExtendHighI16x8S:
  2756  			c.emit(
  2757  				&OperationV128Extend{OriginShape: ShapeI16x8, Signed: true, UseLow: false},
  2758  			)
  2759  		case wasm.OpcodeVecI32x4ExtendLowI16x8U:
  2760  			c.emit(
  2761  				&OperationV128Extend{OriginShape: ShapeI16x8, Signed: false, UseLow: true},
  2762  			)
  2763  		case wasm.OpcodeVecI32x4ExtendHighI16x8U:
  2764  			c.emit(
  2765  				&OperationV128Extend{OriginShape: ShapeI16x8, Signed: false, UseLow: false},
  2766  			)
  2767  		case wasm.OpcodeVecI64x2ExtendLowI32x4S:
  2768  			c.emit(
  2769  				&OperationV128Extend{OriginShape: ShapeI32x4, Signed: true, UseLow: true},
  2770  			)
  2771  		case wasm.OpcodeVecI64x2ExtendHighI32x4S:
  2772  			c.emit(
  2773  				&OperationV128Extend{OriginShape: ShapeI32x4, Signed: true, UseLow: false},
  2774  			)
  2775  		case wasm.OpcodeVecI64x2ExtendLowI32x4U:
  2776  			c.emit(
  2777  				&OperationV128Extend{OriginShape: ShapeI32x4, Signed: false, UseLow: true},
  2778  			)
  2779  		case wasm.OpcodeVecI64x2ExtendHighI32x4U:
  2780  			c.emit(
  2781  				&OperationV128Extend{OriginShape: ShapeI32x4, Signed: false, UseLow: false},
  2782  			)
  2783  		case wasm.OpcodeVecI16x8Q15mulrSatS:
  2784  			c.emit(
  2785  				&OperationV128Q15mulrSatS{},
  2786  			)
  2787  		case wasm.OpcodeVecI16x8ExtMulLowI8x16S:
  2788  			c.emit(
  2789  				&OperationV128ExtMul{OriginShape: ShapeI8x16, Signed: true, UseLow: true},
  2790  			)
  2791  		case wasm.OpcodeVecI16x8ExtMulHighI8x16S:
  2792  			c.emit(
  2793  				&OperationV128ExtMul{OriginShape: ShapeI8x16, Signed: true, UseLow: false},
  2794  			)
  2795  		case wasm.OpcodeVecI16x8ExtMulLowI8x16U:
  2796  			c.emit(
  2797  				&OperationV128ExtMul{OriginShape: ShapeI8x16, Signed: false, UseLow: true},
  2798  			)
  2799  		case wasm.OpcodeVecI16x8ExtMulHighI8x16U:
  2800  			c.emit(
  2801  				&OperationV128ExtMul{OriginShape: ShapeI8x16, Signed: false, UseLow: false},
  2802  			)
  2803  		case wasm.OpcodeVecI32x4ExtMulLowI16x8S:
  2804  			c.emit(
  2805  				&OperationV128ExtMul{OriginShape: ShapeI16x8, Signed: true, UseLow: true},
  2806  			)
  2807  		case wasm.OpcodeVecI32x4ExtMulHighI16x8S:
  2808  			c.emit(
  2809  				&OperationV128ExtMul{OriginShape: ShapeI16x8, Signed: true, UseLow: false},
  2810  			)
  2811  		case wasm.OpcodeVecI32x4ExtMulLowI16x8U:
  2812  			c.emit(
  2813  				&OperationV128ExtMul{OriginShape: ShapeI16x8, Signed: false, UseLow: true},
  2814  			)
  2815  		case wasm.OpcodeVecI32x4ExtMulHighI16x8U:
  2816  			c.emit(
  2817  				&OperationV128ExtMul{OriginShape: ShapeI16x8, Signed: false, UseLow: false},
  2818  			)
  2819  		case wasm.OpcodeVecI64x2ExtMulLowI32x4S:
  2820  			c.emit(
  2821  				&OperationV128ExtMul{OriginShape: ShapeI32x4, Signed: true, UseLow: true},
  2822  			)
  2823  		case wasm.OpcodeVecI64x2ExtMulHighI32x4S:
  2824  			c.emit(
  2825  				&OperationV128ExtMul{OriginShape: ShapeI32x4, Signed: true, UseLow: false},
  2826  			)
  2827  		case wasm.OpcodeVecI64x2ExtMulLowI32x4U:
  2828  			c.emit(
  2829  				&OperationV128ExtMul{OriginShape: ShapeI32x4, Signed: false, UseLow: true},
  2830  			)
  2831  		case wasm.OpcodeVecI64x2ExtMulHighI32x4U:
  2832  			c.emit(
  2833  				&OperationV128ExtMul{OriginShape: ShapeI32x4, Signed: false, UseLow: false},
  2834  			)
  2835  		case wasm.OpcodeVecI16x8ExtaddPairwiseI8x16S:
  2836  			c.emit(
  2837  				&OperationV128ExtAddPairwise{OriginShape: ShapeI8x16, Signed: true},
  2838  			)
  2839  		case wasm.OpcodeVecI16x8ExtaddPairwiseI8x16U:
  2840  			c.emit(
  2841  				&OperationV128ExtAddPairwise{OriginShape: ShapeI8x16, Signed: false},
  2842  			)
  2843  		case wasm.OpcodeVecI32x4ExtaddPairwiseI16x8S:
  2844  			c.emit(
  2845  				&OperationV128ExtAddPairwise{OriginShape: ShapeI16x8, Signed: true},
  2846  			)
  2847  		case wasm.OpcodeVecI32x4ExtaddPairwiseI16x8U:
  2848  			c.emit(
  2849  				&OperationV128ExtAddPairwise{OriginShape: ShapeI16x8, Signed: false},
  2850  			)
  2851  		case wasm.OpcodeVecF64x2PromoteLowF32x4Zero:
  2852  			c.emit(
  2853  				&OperationV128FloatPromote{},
  2854  			)
  2855  		case wasm.OpcodeVecF32x4DemoteF64x2Zero:
  2856  			c.emit(
  2857  				&OperationV128FloatDemote{},
  2858  			)
  2859  		case wasm.OpcodeVecF32x4ConvertI32x4S:
  2860  			c.emit(
  2861  				&OperationV128FConvertFromI{DestinationShape: ShapeF32x4, Signed: true},
  2862  			)
  2863  		case wasm.OpcodeVecF32x4ConvertI32x4U:
  2864  			c.emit(
  2865  				&OperationV128FConvertFromI{DestinationShape: ShapeF32x4, Signed: false},
  2866  			)
  2867  		case wasm.OpcodeVecF64x2ConvertLowI32x4S:
  2868  			c.emit(
  2869  				&OperationV128FConvertFromI{DestinationShape: ShapeF64x2, Signed: true},
  2870  			)
  2871  		case wasm.OpcodeVecF64x2ConvertLowI32x4U:
  2872  			c.emit(
  2873  				&OperationV128FConvertFromI{DestinationShape: ShapeF64x2, Signed: false},
  2874  			)
  2875  		case wasm.OpcodeVecI32x4DotI16x8S:
  2876  			c.emit(
  2877  				&OperationV128Dot{},
  2878  			)
  2879  		case wasm.OpcodeVecI8x16NarrowI16x8S:
  2880  			c.emit(
  2881  				&OperationV128Narrow{OriginShape: ShapeI16x8, Signed: true},
  2882  			)
  2883  		case wasm.OpcodeVecI8x16NarrowI16x8U:
  2884  			c.emit(
  2885  				&OperationV128Narrow{OriginShape: ShapeI16x8, Signed: false},
  2886  			)
  2887  		case wasm.OpcodeVecI16x8NarrowI32x4S:
  2888  			c.emit(
  2889  				&OperationV128Narrow{OriginShape: ShapeI32x4, Signed: true},
  2890  			)
  2891  		case wasm.OpcodeVecI16x8NarrowI32x4U:
  2892  			c.emit(
  2893  				&OperationV128Narrow{OriginShape: ShapeI32x4, Signed: false},
  2894  			)
  2895  		case wasm.OpcodeVecI32x4TruncSatF32x4S:
  2896  			c.emit(
  2897  				&OperationV128ITruncSatFromF{OriginShape: ShapeF32x4, Signed: true},
  2898  			)
  2899  		case wasm.OpcodeVecI32x4TruncSatF32x4U:
  2900  			c.emit(
  2901  				&OperationV128ITruncSatFromF{OriginShape: ShapeF32x4, Signed: false},
  2902  			)
  2903  		case wasm.OpcodeVecI32x4TruncSatF64x2SZero:
  2904  			c.emit(
  2905  				&OperationV128ITruncSatFromF{OriginShape: ShapeF64x2, Signed: true},
  2906  			)
  2907  		case wasm.OpcodeVecI32x4TruncSatF64x2UZero:
  2908  			c.emit(
  2909  				&OperationV128ITruncSatFromF{OriginShape: ShapeF64x2, Signed: false},
  2910  			)
  2911  		default:
  2912  			return fmt.Errorf("unsupported vector instruction in wazeroir: %s", wasm.VectorInstructionName(vecOp))
  2913  		}
  2914  	default:
  2915  		return fmt.Errorf("unsupported instruction in wazeroir: 0x%x", op)
  2916  	}
  2917  
  2918  	// Move the program counter to point to the next instruction.
  2919  	c.pc++
  2920  	return nil
  2921  }
  2922  
  2923  func (c *compiler) nextID() (id uint32) {
  2924  	id = c.currentID + 1
  2925  	c.currentID++
  2926  	return
  2927  }
  2928  
  2929  func (c *compiler) applyToStack(opcode wasm.Opcode) (*uint32, error) {
  2930  	var index uint32
  2931  	var ptr *uint32
  2932  	switch opcode {
  2933  	case
  2934  		// These are the opcodes that is coupled with "index" immediate
  2935  		// and it DOES affect the signature of opcode.
  2936  		wasm.OpcodeCall,
  2937  		wasm.OpcodeCallIndirect,
  2938  		wasm.OpcodeLocalGet,
  2939  		wasm.OpcodeLocalSet,
  2940  		wasm.OpcodeLocalTee,
  2941  		wasm.OpcodeGlobalGet,
  2942  		wasm.OpcodeGlobalSet:
  2943  		// Assumes that we are at the opcode now so skip it before read immediates.
  2944  		v, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  2945  		if err != nil {
  2946  			return nil, fmt.Errorf("reading immediates: %w", err)
  2947  		}
  2948  		c.pc += num
  2949  		index = v
  2950  		ptr = &index
  2951  	default:
  2952  		// Note that other opcodes are free of index
  2953  		// as it doesn't affect the signature of opt code.
  2954  		// In other words, the "index" argument of wasmOpcodeSignature
  2955  		// is ignored there.
  2956  	}
  2957  
  2958  	if c.unreachableState.on {
  2959  		return ptr, nil
  2960  	}
  2961  
  2962  	// Retrieve the signature of the opcode.
  2963  	s, err := c.wasmOpcodeSignature(opcode, index)
  2964  	if err != nil {
  2965  		return nil, err
  2966  	}
  2967  
  2968  	// Manipulate the stack according to the signature.
  2969  	// Note that the following algorithm assumes that
  2970  	// the unknown type is unique in the signature,
  2971  	// and is determined by the actual type on the stack.
  2972  	// The determined type is stored in this typeParam.
  2973  	var typeParam *UnsignedType
  2974  	for i := range s.in {
  2975  		want := s.in[len(s.in)-1-i]
  2976  		actual := c.stackPop()
  2977  		if want == UnsignedTypeUnknown && typeParam != nil {
  2978  			want = *typeParam
  2979  		} else if want == UnsignedTypeUnknown {
  2980  			want = actual
  2981  			typeParam = &actual
  2982  		}
  2983  		if want != actual {
  2984  			return nil, fmt.Errorf("input signature mismatch: want %s but have %s", want, actual)
  2985  		}
  2986  	}
  2987  
  2988  	for _, target := range s.out {
  2989  		if target == UnsignedTypeUnknown && typeParam == nil {
  2990  			return nil, fmt.Errorf("cannot determine type of unknown result")
  2991  		} else if target == UnsignedTypeUnknown {
  2992  			c.stackPush(*typeParam)
  2993  		} else {
  2994  			c.stackPush(target)
  2995  		}
  2996  	}
  2997  
  2998  	return ptr, nil
  2999  }
  3000  
  3001  func (c *compiler) stackPeek() (ret UnsignedType) {
  3002  	ret = c.stack[len(c.stack)-1]
  3003  	return
  3004  }
  3005  
  3006  func (c *compiler) stackPop() (ret UnsignedType) {
  3007  	// No need to check stack bound
  3008  	// as we can assume that all the operations
  3009  	// are valid thanks to validateFunction
  3010  	// at module validation phase.
  3011  	ret = c.stack[len(c.stack)-1]
  3012  	c.stack = c.stack[:len(c.stack)-1]
  3013  	return
  3014  }
  3015  
  3016  func (c *compiler) stackPush(ts ...UnsignedType) {
  3017  	c.stack = append(c.stack, ts...)
  3018  }
  3019  
  3020  // emit adds the operations into the result.
  3021  func (c *compiler) emit(ops ...Operation) {
  3022  	if !c.unreachableState.on {
  3023  		for _, op := range ops {
  3024  			switch o := op.(type) {
  3025  			case *OperationDrop:
  3026  				// If the drop range is nil,
  3027  				// we could remove such operations.
  3028  				// That happens when drop operation is unnecessary.
  3029  				// i.e. when there's no need to adjust stack before jmp.
  3030  				if o.Depth == nil {
  3031  					continue
  3032  				}
  3033  			}
  3034  			c.result.Operations = append(c.result.Operations, op)
  3035  			if false {
  3036  				fmt.Printf("emitting ")
  3037  				formatOperation(os.Stdout, op)
  3038  			}
  3039  		}
  3040  	}
  3041  }
  3042  
  3043  // Emit const expression with default values of the given type.
  3044  func (c *compiler) emitDefaultValue(t wasm.ValueType) {
  3045  	switch t {
  3046  	case wasm.ValueTypeI32:
  3047  		c.stackPush(UnsignedTypeI32)
  3048  		c.emit(&OperationConstI32{Value: 0})
  3049  	case wasm.ValueTypeI64, wasm.ValueTypeExternref, wasm.ValueTypeFuncref:
  3050  		c.stackPush(UnsignedTypeI64)
  3051  		c.emit(&OperationConstI64{Value: 0})
  3052  	case wasm.ValueTypeF32:
  3053  		c.stackPush(UnsignedTypeF32)
  3054  		c.emit(&OperationConstF32{Value: 0})
  3055  	case wasm.ValueTypeF64:
  3056  		c.stackPush(UnsignedTypeF64)
  3057  		c.emit(&OperationConstF64{Value: 0})
  3058  	case wasm.ValueTypeV128:
  3059  		c.stackPush(UnsignedTypeV128)
  3060  		c.emit(&OperationV128Const{Hi: 0, Lo: 0})
  3061  	}
  3062  }
  3063  
  3064  // Returns the "depth" (starting from top of the stack)
  3065  // of the n-th local.
  3066  func (c *compiler) localDepth(index wasm.Index) int {
  3067  	height, ok := c.localIndexToStackHeightInUint64[index]
  3068  	if !ok {
  3069  		panic("BUG")
  3070  	}
  3071  	return c.stackLenInUint64(len(c.stack)) - 1 - int(height)
  3072  }
  3073  
  3074  func (c *compiler) localType(index wasm.Index) (t wasm.ValueType) {
  3075  	if params := uint32(len(c.sig.Params)); index < params {
  3076  		t = c.sig.Params[index]
  3077  	} else {
  3078  		t = c.localTypes[index-params]
  3079  	}
  3080  	return
  3081  }
  3082  
  3083  // getFrameDropRange returns the range (starting from top of the stack) that spans across the (uint64) stack. The range is
  3084  // supposed to be dropped from the stack when the given frame exists or branch into it.
  3085  //
  3086  // * frame is the control frame which the call-site is trying to branch into or exit.
  3087  // * isEnd true if the call-site is handling wasm.OpcodeEnd.
  3088  func (c *compiler) getFrameDropRange(frame *controlFrame, isEnd bool) *InclusiveRange {
  3089  	var start int
  3090  	if !isEnd && frame.kind == controlFrameKindLoop {
  3091  		// If this is not End and the call-site is trying to branch into the Loop control frame,
  3092  		// we have to start executing from the beginning of the loop block.
  3093  		// Therefore, we have to pass the inputs to the frame.
  3094  		start = frame.blockType.ParamNumInUint64
  3095  	} else {
  3096  		start = frame.blockType.ResultNumInUint64
  3097  	}
  3098  	var end int
  3099  	if frame.kind == controlFrameKindFunction {
  3100  		// On the function return, we eliminate all the contents on the stack
  3101  		// including locals (existing below of frame.originalStackLen)
  3102  		end = c.stackLenInUint64(len(c.stack)) - 1
  3103  	} else {
  3104  		end = c.stackLenInUint64(len(c.stack)) - 1 - c.stackLenInUint64(frame.originalStackLenWithoutParam)
  3105  	}
  3106  	if start <= end {
  3107  		return &InclusiveRange{Start: start, End: end}
  3108  	}
  3109  	return nil
  3110  }
  3111  
  3112  func (c *compiler) stackLenInUint64(ceil int) (ret int) {
  3113  	for i := 0; i < ceil; i++ {
  3114  		if c.stack[i] == UnsignedTypeV128 {
  3115  			ret += 2
  3116  		} else {
  3117  			ret++
  3118  		}
  3119  	}
  3120  	return
  3121  }
  3122  
  3123  func (c *compiler) readMemoryArg(tag string) (*MemoryArg, error) {
  3124  	c.result.UsesMemory = true
  3125  	alignment, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  3126  	if err != nil {
  3127  		return nil, fmt.Errorf("reading alignment for %s: %w", tag, err)
  3128  	}
  3129  	c.pc += num
  3130  	offset, num, err := leb128.LoadUint32(c.body[c.pc+1:])
  3131  	if err != nil {
  3132  		return nil, fmt.Errorf("reading offset for %s: %w", tag, err)
  3133  	}
  3134  	c.pc += num
  3135  	return &MemoryArg{Offset: offset, Alignment: alignment}, nil
  3136  }