Repository: tetratelabs/wazero
Pull request #361 (2022-03-11 08:08:39)

cleanups before table element init redo
Notably, this renames `Engine.Compile` -> `NewModuleEngine` and moves table related code to `table.go` and `table_test.go`


Patch:
diff --git a/internal/wasm/engine.go b/internal/wasm/engine.go
index 0430623d..667e5f24 100644
--- a/internal/wasm/engine.go
+++ b/internal/wasm/engine.go
@@ -3,8 +3,14 @@ package internalwasm
 // Engine is a Store-scoped mechanism to compile functions declared or imported by a module.
 // This is a top-level type implemented by an interpreter or JIT compiler.
 type Engine interface {
-	// Compile compiles down the function instances in a module, and returns ModuleEngine for the module.
-	Compile(importedFunctions, moduleFunctions []*FunctionInstance) (ModuleEngine, error)
+	// NewModuleEngine compiles down the function instances in a module, and returns ModuleEngine for the module.
+	//
+	// * importedFunctions: functions this module imports, already compiled in this engine.
+	// * moduleFunctions: functions declared in this module that must be compiled.
+	//
+	// Note: Input parameters must be pre-validated with internalwasm.Module Validate, to ensure no fields are invalid
+	// due to reasons such as out-of-bounds.
+	NewModuleEngine(importedFunctions, moduleFunctions []*FunctionInstance) (ModuleEngine, error)
 }
 
 // ModuleEngine implements function calls for a given module.
@@ -17,7 +23,7 @@ type ModuleEngine interface {
 
 	// Call invokes a function instance f with given parameters.
 	// Returns the results from the function.
-	// The ctx's context.Context will be the outer-most ancestor of the argument to wasm.FunctionVoidReturn, etc.
+	// The ctx's context.Context will be the outer-most ancestor of the argument to wasm.Function.
 	Call(ctx *ModuleContext, f *FunctionInstance, params ...uint64) (results []uint64, err error)
 
 	// Release releases the resources allocated by functions in this ModuleEngine.
diff --git a/internal/wasm/func_validation.go b/internal/wasm/func_validation.go
index 81449f73..264c8969 100644
--- a/internal/wasm/func_validation.go
+++ b/internal/wasm/func_validation.go
@@ -484,7 +484,7 @@ func validateFunction(
 			if table == nil {
 				return fmt.Errorf("table not given while having call_indirect")
 			}
-			if err := valueTypeStack.popAndVerifyType(ValueTypeI32); err != nil {
+			if err = valueTypeStack.popAndVerifyType(ValueTypeI32); err != nil {
 				return fmt.Errorf("cannot pop the in table index's type for call_indirect")
 			}
 			if int(typeIndex) >= len(types) {
@@ -492,7 +492,7 @@ func validateFunction(
 			}
 			funcType := types[typeIndex]
 			for i := 0; i < len(funcType.Params); i++ {
-				if err := valueTypeStack.popAndVerifyType(funcType.Params[len(funcType.Params)-1-i]); err != nil {
+				if err = valueTypeStack.popAndVerifyType(funcType.Params[len(funcType.Params)-1-i]); err != nil {
 					return fmt.Errorf("type mismatch on call_indirect operation input type")
 				}
 			}
@@ -756,12 +756,11 @@ func validateFunction(
 		} else if op == OpcodeElse {
 			bl := controlBlockStack[len(controlBlockStack)-1]
 			bl.elseAt = pc
-			// Check the type soundness of the instructions *before*　 entering this Eles Op.
+			// Check the type soundness of the instructions *before* entering this else Op.
 			if err := valueTypeStack.popResults(bl.blockType.Results, true); err != nil {
 				return fmt.Errorf("invalid instruction results in then instructions")
 			}
-			// Before entring instructions inside else, we pop all the values pushed by
-			// then block.
+			// Before entering instructions inside else, we pop all the values pushed by then block.
 			valueTypeStack.resetAtStackLimit()
 		} else if op == OpcodeEnd {
 			bl := controlBlockStack[len(controlBlockStack)-1]
@@ -847,7 +846,7 @@ type valueTypeStack struct {
 }
 
 const (
-	// Only used in the anlyzeFunction below.
+	// Only used in the analyzeFunction below.
 	valueTypeUnknown = ValueType(0xFF)
 )
 
diff --git a/internal/wasm/interpreter/interpreter.go b/internal/wasm/interpreter/interpreter.go
index 2682457f..5288840b 100644
--- a/internal/wasm/interpreter/interpreter.go
+++ b/internal/wasm/interpreter/interpreter.go
@@ -21,7 +21,7 @@ var callStackCeiling = buildoptions.CallStackCeiling
 
 // engine is an interpreter implementation of internalwasm.Engine
 type engine struct {
-	compiledFunctions map[*wasm.FunctionInstance]*compiledFunction // gurded by mutex.
+	compiledFunctions map[*wasm.FunctionInstance]*compiledFunction // guarded by mutex.
 	mux               sync.RWMutex
 }
 
@@ -67,6 +67,7 @@ type callEngine struct {
 	// stack contains the operands.
 	// Note that all the values are represented as uint64.
 	stack []uint64
+
 	// frames are the function call stack.
 	frames []*callFrame
 }
@@ -126,10 +127,9 @@ func (ce *callEngine) popFrame() (frame *callFrame) {
 }
 
 type callFrame struct {
-	// Program counter representing the current postion
-	// in the f.body.
+	// pc is the program counter representing the current position in compiledFunction.body.
 	pc uint64
-	// The compiled function used in this function frame.
+	// f is the compiled function used in this function frame.
 	f *compiledFunction
 }
 
@@ -148,18 +148,9 @@ type interpreterOp struct {
 	rs     []*wazeroir.InclusiveRange
 }
 
-// Release implements wasm.Engine Release
-func (me *moduleEngine) Release() error {
-	// Release all the function instances declared in this module.
-	for _, cf := range me.compiledFunctions[me.importedFunctionCounts:] {
-		me.parentEngine.deleteCompiledFunction(cf.funcInstance)
-	}
-	return nil
-}
-
-// Compile implements internalwasm.Engine Compile
-func (e *engine) Compile(importedFunctions, moduleFunctions []*wasm.FunctionInstance) (me wasm.ModuleEngine, err error) {
-	modEngine := &moduleEngine{
+// NewModuleEngine implements internalwasm.Engine NewModuleEngine
+func (e *engine) NewModuleEngine(importedFunctions, moduleFunctions []*wasm.FunctionInstance) (wasm.ModuleEngine, error) {
+	me := &moduleEngine{
 		compiledFunctions:      make([]*compiledFunction, 0, len(importedFunctions)+len(moduleFunctions)),
 		parentEngine:           e,
 		importedFunctionCounts: len(importedFunctions),
@@ -170,7 +161,7 @@ func (e *engine) Compile(importedFunctions, moduleFunctions []*wasm.FunctionInst
 		if !ok {
 			return nil, fmt.Errorf("import[%d] func[%s.%s]: uncompiled", idx, f.Module.Name, f.Name)
 		}
-		modEngine.compiledFunctions = append(modEngine.compiledFunctions, cf)
+		me.compiledFunctions = append(me.compiledFunctions, cf)
 	}
 
 	for i, f := range moduleFunctions {
@@ -178,30 +169,39 @@ func (e *engine) Compile(importedFunctions, moduleFunctions []*wasm.FunctionInst
 		if f.Kind == wasm.FunctionKindWasm {
 			ir, err := wazeroir.Compile(f)
 			if err != nil {
-				_ = modEngine.Release()
+				_ = me.Release()
 				// TODO(Adrian): extract Module.funcDesc so that errors here have more context
 				return nil, fmt.Errorf("function[%d/%d] failed to lower to wazeroir: %w", i, len(moduleFunctions)-1, err)
 			}
 
 			compiled, err = e.lowerIROps(f, ir.Operations)
 			if err != nil {
-				_ = modEngine.Release()
+				_ = me.Release()
 				return nil, fmt.Errorf("function[%d/%d] failed to convert wazeroir operations: %w", i, len(moduleFunctions)-1, err)
 			}
 		} else {
 			compiled = &compiledFunction{hostFn: f.GoFunc, funcInstance: f}
 		}
-		compiled.moduleEngine = modEngine
-		modEngine.compiledFunctions = append(modEngine.compiledFunctions, compiled)
+		compiled.moduleEngine = me
+		me.compiledFunctions = append(me.compiledFunctions, compiled)
 
 		// Add the compiled function to the store-wide engine as well so that
 		// the future importing module can refer the function instance.
 		e.addCompiledFunction(f, compiled)
 	}
-	return modEngine, nil
+	return me, nil
+}
+
+// Release implements internalwasm.Engine Release
+func (me *moduleEngine) Release() error {
+	// Release all the function instances declared in this module.
+	for _, cf := range me.compiledFunctions[me.importedFunctionCounts:] {
+		me.parentEngine.deleteCompiledFunction(cf.funcInstance)
+	}
+	return nil
 }
 
-// Lowers the wazeroir operations to engine friendly struct.
+// lowerIROps lowers the wazeroir operations to engine friendly struct.
 func (e *engine) lowerIROps(f *wasm.FunctionInstance,
 	ops []wazeroir.Operation) (*compiledFunction, error) {
 	ret := &compiledFunction{funcInstance: f}
@@ -219,7 +219,7 @@ func (e *engine) lowerIROps(f *wasm.FunctionInstance,
 				cb(address)
 			}
 			delete(onLabelAddressResolved, labelKey)
-			// We just ignore the lable operation
+			// We just ignore the label operation
 			// as we translate branch operations to the direct address jmp.
 			continue
 		case *wazeroir.OperationBr:
diff --git a/internal/wasm/jit/compiler.go b/internal/wasm/jit/compiler.go
index c0b56a22..3f7bcd95 100644
--- a/internal/wasm/jit/compiler.go
+++ b/internal/wasm/jit/compiler.go
@@ -10,11 +10,11 @@ type compiler interface {
 	// String is for debugging purpose.
 	String() string
 	// compilePreamble is called before compiling any wazeroir operation.
-	// This is used, for example, to initilize the reserved registers, etc.
+	// This is used, for example, to initialize the reserved registers, etc.
 	compilePreamble() error
 	// compile generates the byte slice of native code.
 	// stackPointerCeil is the max stack pointer that the target function would reach.
-	// staticData is compiledFunctionStaticData for the resutling native code.
+	// staticData is compiledFunctionStaticData for the resulting native code.
 	compile() (code []byte, staticData compiledFunctionStaticData, stackPointerCeil uint64, err error)
 	// compileHostFunction emits the trampoline code from which native code can jump into the host function.
 	// TODO: maybe we wouldn't need to have trampoline for host functions.
@@ -24,26 +24,26 @@ type compiler interface {
 	// See wazeroir.OperationLabel
 	compileLabel(o *wazeroir.OperationLabel) (skipThisLabel bool)
 	// compileUnreachable adds instructions to return to engine with jitCallStatusCodeUnreachable status.
-	// See wasm.OpcodeUnreachable
+	// See internalwasm.OpcodeUnreachable
 	compileUnreachable() error
 	// compileSwap adds instruction to swap the stack top value with the target in the Wasm value stack.
 	// The values are might be on registers or memory-stack at runtime, so compiler implementations
 	// emit instructions to swap values depending these locations.
-	// See wazeroir.OpeationBrIf
+	// See wazeroir.OperationBrIf
 	compileSwap(o *wazeroir.OperationSwap) error
 	// compileGlobalGet adds instructions to read the value of the given index in the ModuleInstance.Globals
 	// and push the value onto the stack.
-	// See wasm.OpcodeGlobalGet
+	// See internalwasm.OpcodeGlobalGet
 	compileGlobalGet(o *wazeroir.OperationGlobalGet) error
 	// compileGlobalSet adds instructions to set the top value on the stack to the given index in the ModuleInstance.Globals.
-	// See wasm.OpcodeGlobalSet
+	// See internalwasm.OpcodeGlobalSet
 	compileGlobalSet(o *wazeroir.OperationGlobalSet) error
 	// compileBr adds instructions to branch into the given label.
-	// See wasm.OpcodeBr
+	// See internalwasm.OpcodeBr
 	compileBr(o *wazeroir.OperationBr) error
-	// compileBrIf adds instructions to pops a value and branch into ".then" lable if the value equals 1.
+	// compileBrIf adds instructions to pops a value and branch into ".then" label if the value equals 1.
 	// Otherwise, the code branches into ".else" label.
-	// See wasm.OpcodeBrIf and wazeroir.OpeationBrIf
+	// See internalwasm.OpcodeBrIf and wazeroir.OperationBrIf
 	compileBrIf(o *wazeroir.OperationBrIf) error
 	// compileBrTable adds instructions to do br_table operation.
 	// A br_table operation has list of targets and default target, and
@@ -52,11 +52,11 @@ type compiler interface {
 	//
 	// For example, assume we have operations like {default: L_DEFAULT, targets: [L0, L1, L2]}.
 	// If "index" >= len(defaults), then branch into the L_DEFAULT label.
-	// Othewise, we enter label of targets[index].
-	// See wasm.OpcodeBrTable
+	// Otherwise, we enter label of targets[index].
+	// See internalwasm.OpcodeBrTable
 	compileBrTable(o *wazeroir.OperationBrTable) error
-	// compileCall adds instructions to call into a funcion of the given index.
-	// See wasm.OpcodeCall
+	// compileCall adds instructions to call into a function of the given index.
+	// See internalwasm.OpcodeCall
 	compileCall(o *wazeroir.OperationCall) error
 	// compileCallIndirect adds instructions to perform call_indirect operation.
 	// This consumes the one value from the top of stack (called "offset"),
@@ -77,7 +77,7 @@ type compiler interface {
 	compileDrop(o *wazeroir.OperationDrop) error
 	// compileSelect uses top three values on the stack. For example, if we have stack as [..., x1, x2, c]
 	// and the value "c" equals zero, then the stack results in [..., x1], otherwise, [..., x2].
-	// See wasm.OpcodeSelect
+	// See internalwasm.OpcodeSelect
 	compileSelect() error
 	// compilePick adds instructions to copy a value on the given location in the Wasm value stack,
 	// and push the copied value onto the top of the stack.
@@ -85,118 +85,118 @@ type compiler interface {
 	compilePick(o *wazeroir.OperationPick) error
 	// compileAdd adds instructions to pop two values from the stack, add these two values, and push
 	// back the result onto the stack.
-	// See wasm.OpcodeI32Add wasm.OpcodeI64Add wasm.OpcodeF32Add wasm.OpcodeF64Add
+	// See internalwasm.OpcodeI32Add internalwasm.OpcodeI64Add internalwasm.OpcodeF32Add internalwasm.OpcodeF64Add
 	compileAdd(o *wazeroir.OperationAdd) error
 	// compileSub adds instructions to pop two values from the stack, subtract the top from the second one, and push
 	// back the result onto the stack.
-	// See wasm.OpcodeI32Sub wasm.OpcodeI64Sub wasm.OpcodeF32Sub wasm.OpcodeF64Sub
+	// See internalwasm.OpcodeI32Sub internalwasm.OpcodeI64Sub internalwasm.OpcodeF32Sub internalwasm.OpcodeF64Sub
 	compileSub(o *wazeroir.OperationSub) error
 	// compileMul adds instructions to pop two values from the stack, multiply these two values, and push
 	// back the result onto the stack.
-	// See wasm.OpcodeI32Mul wasm.OpcodeI64Mul wasm.OpcodeF32Mul wasm.OpcodeF64Mul
+	// See internalwasm.OpcodeI32Mul internalwasm.OpcodeI64Mul internalwasm.OpcodeF32Mul internalwasm.OpcodeF64Mul
 	compileMul(o *wazeroir.OperationMul) error
 	// compileClz emits instructions to count up the leading zeros in the
 	// current top of the stack, and push the count result.
 	// For example, stack of [..., 0x00_ff_ff_ff] results in [..., 8].
-	// See wasm.OpcodeI32Clz wasm.OpcodeI64Clz
+	// See internalwasm.OpcodeI32Clz internalwasm.OpcodeI64Clz
 	compileClz(o *wazeroir.OperationClz) error
 	// compileCtz emits instructions to count up the trailing zeros in the
 	// current top of the stack, and push the count result.
 	// For example, stack of [..., 0xff_ff_ff_00] results in [..., 8].
-	// See wasm.OpcodeI32Ctz wasm.OpcodeI64Ctz
+	// See internalwasm.OpcodeI32Ctz internalwasm.OpcodeI64Ctz
 	compileCtz(o *wazeroir.OperationCtz) error
 	// compilePopcnt emits instructions to count up the number of set bits in the
 	// current top of the stack, and push the count result.
 	// For example, stack of [..., 0b00_00_00_11] results in [..., 2].
-	// See wasm.OpcodeI32Popcnt wasm.OpcodeI64Popcnt
+	// See internalwasm.OpcodeI32Popcnt internalwasm.OpcodeI64Popcnt
 	compilePopcnt(o *wazeroir.OperationPopcnt) error
 	// compileDiv emits the instructions to perform division on the top two values on the stack.
-	// See wasm.OpcodeI32DivS wasm.OpcodeI32DivU wasm.OpcodeI64DivS wasm.OpcodeI64DivU wasm.OpcodeF32Div wasm.OpcodeF64Div
+	// See internalwasm.OpcodeI32DivS internalwasm.OpcodeI32DivU internalwasm.OpcodeI64DivS internalwasm.OpcodeI64DivU internalwasm.OpcodeF32Div internalwasm.OpcodeF64Div
 	compileDiv(o *wazeroir.OperationDiv) error
 	// compileRem emits the instructions to perform division on the top
 	// two values of integer type on the stack and puts the remainder of the result
 	// onto the stack. For example, stack [..., 10, 3] results in [..., 1] where
 	// the quotient is discarded.
-	// See wasm.OpcodeI32RemS wasm.OpcodeI32RemU wasm.OpcodeI64RemS wasm.OpcodeI64RemU
+	// See internalwasm.OpcodeI32RemS internalwasm.OpcodeI32RemU internalwasm.OpcodeI64RemS internalwasm.OpcodeI64RemU
 	compileRem(o *wazeroir.OperationRem) error
 	// compileAnd emits instructions to perform logical "and" operation on
 	// top two values on the stack, and push the result.
-	// See wasm.OpcodeI32And wasm.OpcodeI64And
+	// See internalwasm.OpcodeI32And internalwasm.OpcodeI64And
 	compileAnd(o *wazeroir.OperationAnd) error
 	// compileOr emits instructions to perform logical "or" operation on
 	// top two values on the stack, and pushes the result.
-	// See wasm.OpcodeI32Or wasm.OpcodeI64Or
+	// See internalwasm.OpcodeI32Or internalwasm.OpcodeI64Or
 	compileOr(o *wazeroir.OperationOr) error
 	// compileXor emits instructions to perform logical "xor" operation on
 	// top two values on the stack, and pushes the result.
-	// See wasm.OpcodeI32Xor wasm.OpcodeI64Xor
+	// See internalwasm.OpcodeI32Xor internalwasm.OpcodeI64Xor
 	compileXor(o *wazeroir.OperationXor) error
 	// compileShl emits instructions to perform a shift-left operation on
 	// top two values on the stack, and pushes the result.
-	// See wasm.OpcodeI32Shl wasm.OpcodeI64Shl
+	// See internalwasm.OpcodeI32Shl internalwasm.OpcodeI64Shl
 	compileShl(o *wazeroir.OperationShl) error
 	// compileShr emits instructions to perform a shift-right operation on
 	// top two values on the stack, and pushes the result.
-	// See wasm.OpcodeI32Shr wasm.OpcodeI64Shr
+	// See internalwasm.OpcodeI32Shr internalwasm.OpcodeI64Shr
 	compileShr(o *wazeroir.OperationShr) error
 	// compileRotl emits instructions to perform a rotate-left operation on
 	// top two values on the stack, and pushes the result.
-	// See wasm.OpcodeI32Rotl wasm.OpcodeI64Rotl
+	// See internalwasm.OpcodeI32Rotl internalwasm.OpcodeI64Rotl
 	compileRotl(o *wazeroir.OperationRotl) error
 	// compileRotr emits instructions to perform a rotate-right operation on
 	// top two values on the stack, and pushes the result.
-	// See wasm.OpcodeI32Rotr wasm.OpcodeI64Rotr
+	// See internalwasm.OpcodeI32Rotr internalwasm.OpcodeI64Rotr
 	compileRotr(o *wazeroir.OperationRotr) error
 	// compileAbs adds instructions to replace the top value of float type on the stack with its absolute value.
 	// For example, stack [..., -1.123] results in [..., 1.123].
-	// See wasm.OpcodeF32Abs wasm.OpcodeF64Abs
+	// See internalwasm.OpcodeF32Abs internalwasm.OpcodeF64Abs
 	compileAbs(o *wazeroir.OperationAbs) error
 	// compileNeg adds instructions to replace the top value of float type on the stack with its negated value.
 	// For example, stack [..., -1.123] results in [..., 1.123].
-	// See wasm.OpcodeF32Neg wasm.OpcodeF64Neg
+	// See internalwasm.OpcodeF32Neg internalwasm.OpcodeF64Neg
 	compileNeg(o *wazeroir.OperationNeg) error
 	// compileCeil adds instructions to replace the top value of float type on the stack with its ceiling value.
 	// For example, stack [..., 1.123] results in [..., 2.0]. This is equivalent to math.Ceil.
-	// See wasm.OpcodeF32Ceil wasm.OpcodeF64Ceil
+	// See internalwasm.OpcodeF32Ceil internalwasm.OpcodeF64Ceil
 	compileCeil(o *wazeroir.OperationCeil) error
 	// compileFloor adds instructions to replace the top value of float type on the stack with its floor value.
 	// For example, stack [..., 1.123] results in [..., 1.0]. This is equivalent to math.Floor.
-	// See wasm.OpcodeF32Floor wasm.OpcodeF64Floor
+	// See internalwasm.OpcodeF32Floor internalwasm.OpcodeF64Floor
 	compileFloor(o *wazeroir.OperationFloor) error
 	// compileTrunc adds instructions to replace the top value of float type on the stack with its truncated value.
 	// For example, stack [..., 1.9] results in [..., 1.0]. This is equivalent to math.Trunc.
-	// See wasm.OpcodeF32Trunc wasm.OpcodeF64Trunc
+	// See internalwasm.OpcodeF32Trunc internalwasm.OpcodeF64Trunc
 	compileTrunc(o *wazeroir.OperationTrunc) error
 	// compileNearest adds instructions to replace the top value of float type on the stack with its nearest integer value.
 	// For example, stack [..., 1.9] results in [..., 2.0]. This is *not* equivalent to math.Round and instead has the same
-	// the semantics of LLVM's rint instrinsic. See https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic.
+	// the semantics of LLVM's rint intrinsic. See https://llvm.org/docs/LangRef.html#llvm-rint-intrinsic.
 	// For example, math.Round(-4.5) produces -5 while we want to produce -4.
-	// See wasm.OpcodeF32Nearest wasm.OpcodeF64Nearest
+	// See internalwasm.OpcodeF32Nearest internalwasm.OpcodeF64Nearest
 	compileNearest(o *wazeroir.OperationNearest) error
 	// compileSqrt adds instructions to replace the top value of float type on the stack with its square root.
 	// For example, stack [..., 9.0] results in [..., 3.0]. This is equivalent to "math.Sqrt".
-	// See wasm.OpcodeF32Sqrt wasm.OpcodeF64Sqrt
+	// See internalwasm.OpcodeF32Sqrt internalwasm.OpcodeF64Sqrt
 	compileSqrt(o *wazeroir.OperationSqrt) error
 	// compileMin adds instructions to pop two values from the stack, and push back the maximum of
 	// these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 1.9].
 	// Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN,
 	// which is a different behavior different from math.Min.
-	// See wasm.OpcodeF32Min wasm.OpcodeF64Min
+	// See internalwasm.OpcodeF32Min internalwasm.OpcodeF64Min
 	compileMin(o *wazeroir.OperationMin) error
 	// compileMax adds instructions to pop two values from the stack, and push back the maximum of
 	// these two values onto the stack. For example, stack [..., 100.1, 1.9] results in [..., 100.1].
 	// Note: WebAssembly specifies that min/max must always return NaN if one of values is NaN,
 	// which is a different behavior different from math.Max.
-	// See wasm.OpcodeF32Max wasm.OpcodeF64Max
+	// See internalwasm.OpcodeF32Max internalwasm.OpcodeF64Max
 	compileMax(o *wazeroir.OperationMax) error
 	// compileCopysign adds instructions to pop two float values from the stack, and copy the signbit of
 	// the first-popped value to the last one.
 	// For example, stack [..., 1.213, -5.0] results in [..., -1.213].
-	// See wasm.OpcodeF32Copysign wasm.OpcodeF64Copysign
+	// See internalwasm.OpcodeF32Copysign internalwasm.OpcodeF64Copysign
 	compileCopysign(o *wazeroir.OperationCopysign) error
 	// compileI32WrapFromI64 adds instructions to replace the 64-bit int on top of the stack
 	// with the corresponding 32-bit integer. This is equivalent to uint64(uint32(v)) in Go.
-	// See wasm.OpcodeI32WrapI64.
+	// See internalwasm.OpcodeI32WrapI64.
 	compileI32WrapFromI64() error
 	// compileITruncFromF adds instructions to replace the top value of float type on the stack with
 	// the corresponding int value. This is equivalent to int32(math.Trunc(float32(x))), uint32(math.Trunc(float64(x))), etc in Go.
@@ -217,124 +217,124 @@ type compiler interface {
 	compileFConvertFromI(o *wazeroir.OperationFConvertFromI) error
 	// compileF32DemoteFromF64 adds instructions to replace the 64-bit float on top of the stack
 	// with the corresponding 32-bit float. This is equivalent to float32(float64(v)) in Go.
-	// See wasm.OpcodeF32DemoteF64
+	// See internalwasm.OpcodeF32DemoteF64
 	compileF32DemoteFromF64() error
 	// compileF64PromoteFromF32 adds instructions to replace the 32-bit float on top of the stack
 	// with the corresponding 64-bit float. This is equivalent to float64(float32(v)) in Go.
-	// See wasm.OpcodeF64PromoteF32
+	// See internalwasm.OpcodeF64PromoteF32
 	compileF64PromoteFromF32() error
 	// compileI32ReinterpretFromF32 adds instructions to reinterpret the 32-bit float on top of the stack
 	// as a 32-bit integer by preserving the bit representation. If the value is on the stack,
 	// this is no-op as there is nothing to do for converting type.
-	// See wasm.OpcodeI32ReinterpretF32.
+	// See internalwasm.OpcodeI32ReinterpretF32.
 	compileI32ReinterpretFromF32() error
 	// compileI64ReinterpretFromF64 adds instructions to reinterpret the 64-bit float on top of the stack
 	// as a 64-bit integer by preserving the bit representation.
-	// See wasm.OpcodeI64ReinterpretF64.
+	// See internalwasm.OpcodeI64ReinterpretF64.
 	compileI64ReinterpretFromF64() error
 	// compileF32ReinterpretFromI32 adds instructions to reinterpret the 32-bit int on top of the stack
 	// as a 32-bit float by preserving the bit representation.
-	// See wasm.OpcodeF32ReinterpretI32.
+	// See internalwasm.OpcodeF32ReinterpretI32.
 	compileF32ReinterpretFromI32() error
 	// compileF64ReinterpretFromI64 adds instructions to reinterpret the 64-bit int on top of the stack
 	// as a 64-bit float by preserving the bit representation.
-	// See wasm.OpcodeF64ReinterpretI64.
+	// See internalwasm.OpcodeF64ReinterpretI64.
 	compileF64ReinterpretFromI64() error
 	// compileExtend adds instructions to extend the 32-bit signed or unsigned int on top of the stack
-	// as a 64-bit integer of coressponding signedness. For unsigned case, this is just reinterpreting the
+	// as a 64-bit integer of corresponding signedness. For unsigned case, this is just reinterpreting the
 	// underlying bit pattern as 64-bit integer. For signed case, this is sign-extension which preserves the
 	// original integer's sign.
-	// See wasm.OpcodeI64ExtendI32S wasm.OpcodeI64ExtendI32U
+	// See internalwasm.OpcodeI64ExtendI32S internalwasm.OpcodeI64ExtendI32U
 	compileExtend(o *wazeroir.OperationExtend) error
 	// compileEq adds instructions to pop two values from the stack and push 1 if they equal otherwise 0.
-	// See wasm.OpcodeI32Eq wasm.OpcodeI64Eq
+	// See internalwasm.OpcodeI32Eq internalwasm.OpcodeI64Eq
 	compileEq(o *wazeroir.OperationEq) error
 	// compileEq adds instructions to pop two values from the stack and push 0 if they equal otherwise 1.
-	// See wasm.OpcodeI32Ne wasm.OpcodeI64Ne
+	// See internalwasm.OpcodeI32Ne internalwasm.OpcodeI64Ne
 	compileNe(o *wazeroir.OperationNe) error
 	// compileEq adds instructions to pop a value from the stack and push 1 if it equals zero, 0.
-	// See wasm.OpcodeI32Eqz wasm.OpcodeI64Eqz
+	// See internalwasm.OpcodeI32Eqz internalwasm.OpcodeI64Eqz
 	compileEqz(o *wazeroir.OperationEqz) error
 	// compileLt adds instructions to pop two values from the stack and push 1 if the second is less than the top one. Otherwise 0.
-	// See wasm.OpcodeI32Lt wasm.OpcodeI64Lt
+	// See internalwasm.OpcodeI32Lt internalwasm.OpcodeI64Lt
 	compileLt(o *wazeroir.OperationLt) error
 	// compileGt adds instructions to pop two values from the stack and push 1 if the second is greater than the top one. Otherwise 0.
-	// See wasm.OpcodeI32Gt wasm.OpcodeI64Gt
+	// See internalwasm.OpcodeI32Gt internalwasm.OpcodeI64Gt
 	compileGt(o *wazeroir.OperationGt) error
 	// compileLe adds instructions to pop two values from the stack and push 1 if the second is less than or equals the top one. Otherwise 0.
-	// See wasm.OpcodeI32Le wasm.OpcodeI64Le
+	// See internalwasm.OpcodeI32Le internalwasm.OpcodeI64Le
 	compileLe(o *wazeroir.OperationLe) error
 	// compileLe adds instructions to pop two values from the stack and push 1 if the second is greater than or equals the top one. Otherwise 0.
-	// See wasm.OpcodeI32Ge wasm.OpcodeI64Ge
+	// See internalwasm.OpcodeI32Ge internalwasm.OpcodeI64Ge
 	compileGe(o *wazeroir.OperationGe) error
 	// compileLoad adds instructions to perform load instruction in WebAssembly.
-	// See wasm.OpcodeI32Load wasm.OpcodeI64Load wasm.OpcodeF32Load wasm.OpcodeF64Load
+	// See internalwasm.OpcodeI32Load internalwasm.OpcodeI64Load internalwasm.OpcodeF32Load internalwasm.OpcodeF64Load
 	compileLoad(o *wazeroir.OperationLoad) error
 	// compileLoad8 adds instructions to perform load8 instruction in WebAssembly.
 	// The resulting code checks the memory boundary at runtime, and exit the function with jitCallStatusCodeMemoryOutOfBounds if out-of-bounds access happens.
-	// See wasm.OpcodeI32Load8S wasm.OpcodeI32Load8U wasm.OpcodeI64Load8S wasm.OpcodeI64Load8U
+	// See internalwasm.OpcodeI32Load8S internalwasm.OpcodeI32Load8U internalwasm.OpcodeI64Load8S internalwasm.OpcodeI64Load8U
 	compileLoad8(o *wazeroir.OperationLoad8) error
 	// compileLoad16 adds instructions to perform load16 instruction in WebAssembly.
 	// The resulting code checks the memory boundary at runtime, and exit the function with jitCallStatusCodeMemoryOutOfBounds if out-of-bounds access happens.
-	// See wasm.OpcodeI32Load16S wasm.OpcodeI32Load16U wasm.OpcodeI64Load16S wasm.OpcodeI64Load16U
+	// See internalwasm.OpcodeI32Load16S internalwasm.OpcodeI32Load16U internalwasm.OpcodeI64Load16S internalwasm.OpcodeI64Load16U
 	compileLoad16(o *wazeroir.OperationLoad16) error
 	// compileLoad32 adds instructions to perform load32 instruction in WebAssembly.
 	// The resulting code checks the memory boundary at runtime, and exit the function with jitCallStatusCodeMemoryOutOfBounds
 	// if out-of-bounds access happens.
-	// See wasm.OpcodeI64Load32S wasm.OpcodeI64Load32U
+	// See internalwasm.OpcodeI64Load32S internalwasm.OpcodeI64Load32U
 	compileLoad32(o *wazeroir.OperationLoad32) error
 	// compileStore adds instructions to perform store instruction in WebAssembly.
 	// The resulting code checks the memory boundary at runtime, and exit the function with jitCallStatusCodeMemoryOutOfBounds
 	// if out-of-bounds access happens.
-	// See wasm.OpcodeI32Store wasm.OpcodeI64Store wasm.OpcodeF32Store wasm.OpcodeF64Store
+	// See internalwasm.OpcodeI32Store internalwasm.OpcodeI64Store internalwasm.OpcodeF32Store internalwasm.OpcodeF64Store
 	compileStore(o *wazeroir.OperationStore) error
 	// compileStore8 adds instructions to perform store8 instruction in WebAssembly.
 	// The resulting code checks the memory boundary at runtime, and exit the function with jitCallStatusCodeMemoryOutOfBounds
 	// if out-of-bounds access happens.
-	// See wasm.OpcodeI32Store8S wasm.OpcodeI32Store8U wasm.OpcodeI64Store8S wasm.OpcodeI64Store8U
+	// See internalwasm.OpcodeI32Store8S internalwasm.OpcodeI32Store8U internalwasm.OpcodeI64Store8S internalwasm.OpcodeI64Store8U
 	compileStore8(o *wazeroir.OperationStore8) error
 	// compileStore16 adds instructions to perform store16 instruction in WebAssembly.
 	// The resulting code checks the memory boundary at runtime, and exit the function with jitCallStatusCodeMemoryOutOfBounds
 	// if out-of-bounds access happens.
-	// See wasm.OpcodeI32Store16S wasm.OpcodeI32Store16U wasm.OpcodeI64Store16S wasm.OpcodeI64Store16U
+	// See internalwasm.OpcodeI32Store16S internalwasm.OpcodeI32Store16U internalwasm.OpcodeI64Store16S internalwasm.OpcodeI64Store16U
 	compileStore16(o *wazeroir.OperationStore16) error
 	// compileStore32 adds instructions to perform store32 instruction in WebAssembly.
 	// The resulting code checks the memory boundary at runtime, and exit the function with jitCallStatusCodeMemoryOutOfBounds
 	// if out-of-bounds access happens.
-	// See wasm.OpcodeI64Store32S wasm.OpcodeI64Store32U
+	// See internalwasm.OpcodeI64Store32S internalwasm.OpcodeI64Store32U
 	compileStore32(o *wazeroir.OperationStore32) error
 	// compileMemorySize adds instruction to pop a value from the stack, grow the memory buffer according to the value,
 	// and push the previous page size onto the stack.
-	// See wasm.OpcodeMemoryGrow
+	// See internalwasm.OpcodeMemoryGrow
 	compileMemoryGrow() error
 	// compileMemorySize adds instruction to read the current page size of memory instance and push it onto the stack.
-	// See wasm.OpcodeMemorySize
+	// See internalwasm.OpcodeMemorySize
 	compileMemorySize() error
 	// compileConstI32 adds instruction to push the given constant i32 value onto the stack.
-	// See wasm.OpcodeI32Const
+	// See internalwasm.OpcodeI32Const
 	compileConstI32(o *wazeroir.OperationConstI32) error
 	// compileConstI32 adds instruction to push the given constant i64 value onto the stack.
-	// See wasm.OpcodeI64Const
+	// See internalwasm.OpcodeI64Const
 	compileConstI64(o *wazeroir.OperationConstI64) error
 	// compileConstI32 adds instruction to push the given constant f32 value onto the stack.
-	// See wasm.OpcodeF32Const
+	// See internalwasm.OpcodeF32Const
 	compileConstF32(o *wazeroir.OperationConstF32) error
 	// compileConstI32 adds instruction to push the given constant f64 value onto the stack.
-	// See wasm.OpcodeF64Const
+	// See internalwasm.OpcodeF64Const
 	compileConstF64(o *wazeroir.OperationConstF64) error
 	// compileSignExtend32From8 adds instruction to sign-extends the first 8-bits of 32-bit in as signed 32-bit int.
-	// See wasm.OpcodeI32Extend8S
+	// See internalwasm.OpcodeI32Extend8S
 	compileSignExtend32From8() error
 	// compileSignExtend32From16 adds instruction to sign-extends the first 16-bits of 32-bit in as signed 32-bit int.
-	// See wasm.OpcodeI32Extend16S
+	// See internalwasm.OpcodeI32Extend16S
 	compileSignExtend32From16() error
 	// compileSignExtend64From8 adds instruction to sign-extends the first 8-bits of 64-bit in as signed 64-bit int.
-	// See wasm.OpcodeI64Extend8S
+	// See internalwasm.OpcodeI64Extend8S
 	compileSignExtend64From8() error
 	// compileSignExtend64From16 adds instruction to sign-extends the first 16-bits of 64-bit in as signed 64-bit int.
-	// See wasm.OpcodeI64Extend16S
+	// See internalwasm.OpcodeI64Extend16S
 	compileSignExtend64From16() error
 	// compileSignExtend64From32 adds instruction to sign-extends the first 32-bits of 64-bit in as signed 64-bit int.
-	// See wasm.OpcodeI64Extend32S
+	// See internalwasm.OpcodeI64Extend32S
 	compileSignExtend64From32() error
 }
diff --git a/internal/wasm/jit/engine.go b/internal/wasm/jit/engine.go
index cb56e6f1..69b51a6f 100644
--- a/internal/wasm/jit/engine.go
+++ b/internal/wasm/jit/engine.go
@@ -118,7 +118,7 @@ type (
 
 		// stackBasePointer is updated whenever we make function calls.
 		// Background: Functions might be compiled as if they use the stack from the bottom.
-		// However in reality, they have to use it from the middle of the stack depending on
+		// However, in reality, they have to use it from the middle of the stack depending on
 		// when these function calls are made. So instead of accessing stack via stackPointer alone,
 		// functions are compiled so they access the stack via [stackBasePointer](fixed for entire function) + [stackPointer].
 		// More precisely, stackBasePointer is set to [callee's stack pointer] + [callee's stack base pointer] - [caller's params].
@@ -179,7 +179,7 @@ type (
 
 	// staticData holds the read-only data (i.e. out side of codeSegment which is marked as executable) per function.
 	// This is used to store jump tables for br_table instructions.
-	// The primary index is the logical sepration of multiple data, for example data[0] and data[1]
+	// The primary index is the logical separation of multiple data, for example data[0] and data[1]
 	// correspond to different jump tables for different br_table instructions.
 	compiledFunctionStaticData = [][]byte
 )
@@ -190,14 +190,14 @@ const (
 	// Offsets for moduleEngine.compiledFunctions
 	moduleEngineCompiledFunctionsOffset = 0
 
-	// Offsets for callEngine.globalContext.
+	// Offsets for callEngine globalContext.
 	callEngineGlobalContextValueStackElement0AddressOffset     = 0
 	callEngineGlobalContextValueStackLenOffset                 = 8
 	callEngineGlobalContextCallFrameStackElement0AddressOffset = 16
 	callEngineGlobalContextCallFrameStackLenOffset             = 24
 	callEngineGlobalContextCallFrameStackPointerOffset         = 32
 
-	// Offsets for callEngine.moduleContext.
+	// Offsets for callEngine moduleContext.
 	callEngineModuleContextModuleInstanceAddressOffset            = 40
 	callEngineModuleContextGlobalElement0AddressOffset            = 48
 	callEngineModuleContextMemoryElement0AddressOffset            = 56
@@ -206,11 +206,11 @@ const (
 	callEngineModuleContextTableSliceLenOffset                    = 80
 	callEngineModuleContextCompiledFunctionsElement0AddressOffset = 88
 
-	// Offsets for callEngine.valueStackContext.
+	// Offsets for callEngine valueStackContext.
 	callEngineValueStackContextStackPointerOffset     = 96
 	callEngineValueStackContextStackBasePointerOffset = 104
 
-	// Offsets for callEngine.exitContext.
+	// Offsets for callEngine exitContext.
 	callEngineExitContextJITCallStatusCodeOffset          = 112
 	callEngineExitContextBuiltinFunctionCallAddressOffset = 116
 
@@ -226,24 +226,24 @@ const (
 	compiledFunctionStackPointerCeilOffset   = 8
 	compiledFunctionSourceOffset             = 16
 
-	// Offsets for wasm.ModuleInstance
+	// Offsets for internalwasm.ModuleInstance.
 	moduleInstanceGlobalsOffset = 48
 	moduleInstanceMemoryOffset  = 72
 	moduleInstanceTableOffset   = 80
 	moduleInstanceEngineOffset  = 120
 
-	// Offsets for wasm.Table.
+	// Offsets for internalwasm.TableInstance.
 	tableInstanceTableOffset    = 0
 	tableInstanceTableLenOffset = 8
 
-	// Offsets for wasm.FunctionInstance
+	// Offsets for internalwasm.FunctionInstance.
 	functionInstanceTypeIDOffset = 96
 
-	// Offsets for wasm.Memory.
+	// Offsets for internalwasm.MemoryInstance.
 	memoryInstanceBufferOffset    = 0
 	memoryInstanceBufferLenOffset = 8
 
-	// Offsets for wasm.GlobalInstance.
+	// Offsets for internalwasm.GlobalInstance.
 	globalInstanceValueOffset = 8
 
 	// Offsets for Go's interface.
@@ -322,10 +322,10 @@ func (c *callFrame) String() string {
 	)
 }
 
-// Compile implements internalwasm.Engine Compile
-func (e *engine) Compile(importedFunctions, moduleFunctions []*wasm.FunctionInstance) (me wasm.ModuleEngine, err error) {
+// NewModuleEngine implements internalwasm.Engine NewModuleEngine
+func (e *engine) NewModuleEngine(importedFunctions, moduleFunctions []*wasm.FunctionInstance) (wasm.ModuleEngine, error) {
 	imported := len(importedFunctions)
-	modEngine := &moduleEngine{
+	me := &moduleEngine{
 		compiledFunctions:      make([]*compiledFunction, 0, imported+len(moduleFunctions)),
 		parentEngine:           e,
 		importedFunctionCounts: imported,
@@ -336,27 +336,46 @@ func (e *engine) Compile(importedFunctions, moduleFunctions []*wasm.FunctionInst
 		if !ok {
 			return nil, fmt.Errorf("import[%d] func[%s.%s]: uncompiled", idx, f.Module.Name, f.Name)
 		}
-		modEngine.compiledFunctions = append(modEngine.compiledFunctions, cf)
+		me.compiledFunctions = append(me.compiledFunctions, cf)
 	}
 
 	for i, f := range moduleFunctions {
 		var compiled *compiledFunction
+		var err error
 		if f.Kind == wasm.FunctionKindWasm {
 			compiled, err = compileWasmFunction(f)
 		} else {
 			compiled, err = compileHostFunction(f)
 		}
 		if err != nil {
-			_ = modEngine.Release()
+			_ = me.Release()
 			return nil, fmt.Errorf("function[%d/%d] %w", i, len(moduleFunctions)-1, err)
 		}
-		modEngine.compiledFunctions = append(modEngine.compiledFunctions, compiled)
+		me.compiledFunctions = append(me.compiledFunctions, compiled)
 
 		// Add the compiled function to the store-wide engine as well so that
 		// the future importing module can refer the function instance.
 		e.addCompiledFunction(f, compiled)
 	}
-	return modEngine, nil
+
+	return me, nil
+}
+
+// FunctionAddress implements internalwasm.ModuleEngine FunctionAddress
+func (me *moduleEngine) FunctionAddress(index wasm.Index) uintptr {
+	return uintptr(unsafe.Pointer(me.compiledFunctions[index]))
+}
+
+// Release implements internalwasm.ModuleEngine Release
+func (me *moduleEngine) Release() error {
+	// Release all the function instances declared in this module.
+	for _, cf := range me.compiledFunctions[me.importedFunctionCounts:] {
+		if err := munmapCodeSegment(cf.codeSegment); err != nil {
+			return err
+		}
+		me.parentEngine.deleteCompiledFunction(cf.source)
+	}
+	return nil
 }
 
 func (e *engine) deleteCompiledFunction(f *wasm.FunctionInstance) {
@@ -378,23 +397,6 @@ func (e *engine) getCompiledFunction(f *wasm.FunctionInstance) (cf *compiledFunc
 	return
 }
 
-// FunctionAddress implements internalwasm.ModuleEngine FunctionAddress
-func (me *moduleEngine) FunctionAddress(index wasm.Index) uintptr {
-	return uintptr(unsafe.Pointer(me.compiledFunctions[index]))
-}
-
-// Release implements internalwasm.ModuleEngine Release
-func (me *moduleEngine) Release() error {
-	// Release all the function instances declared in this module.
-	for _, cf := range me.compiledFunctions[me.importedFunctionCounts:] {
-		if err := munmapCodeSegment(cf.codeSegment); err != nil {
-			return err
-		}
-		me.parentEngine.deleteCompiledFunction(cf.source)
-	}
-	return nil
-}
-
 // Call implements internalwasm.ModuleEngine Call
 func (me *moduleEngine) Call(ctx *wasm.ModuleContext, f *wasm.FunctionInstance, params ...uint64) (results []uint64, err error) {
 	compiled := me.compiledFunctions[f.Index]
@@ -469,14 +471,14 @@ func newEngine() *engine {
 }
 
 // Do not make these variables as constants, otherwise there would be
-// dangerous memory accees from native code.
+// dangerous memory access from native code.
 //
 // Background: Go has a mechanism called "goroutine stack-shrink" where Go
 // runtime shrinks Gorotuine's stack when it is GCing. Shrinking means that
 // all the contents on the goroutine stack will be relocated by runtime,
 // Therefore, the memory address of these contents change undeterministically.
 // Not only shrinks, but also Goruntime grows the goroutine stack at any point
-// of function call entries, which also might end up relcating contents.
+// of function call entries, which also might end up relocating contents.
 //
 // On the other hand, we hold pointers to the data region of value stack and
 // callframe stack slices and use these raw pointers from native code.
@@ -681,7 +683,7 @@ func (ce *callEngine) pushCallFrame(f *compiledFunction) {
 	//                 |     |
 	// [...., A, B, C, D, E, _, _ ]
 	//
-	// That maens the next stack base poitner is calculated as follows (note stack pointer is relative to base):
+	// That means the next stack base pointer is calculated as follows (note stack pointer is relative to base):
 	ce.valueStackContext.stackBasePointer =
 		ce.valueStackContext.stackBasePointer + ce.valueStackContext.stackPointer - uint64(len(f.source.Type.Params))
 }
@@ -723,7 +725,7 @@ func (ce *callEngine) builtinFunctionMemoryGrow(mem *wasm.MemoryInstance) {
 	res := mem.Grow(uint32(newPages))
 	ce.pushValue(uint64(res))
 
-	// Update the moduleContext's ields as they become stale after the update ^^.
+	// Update the moduleContext fields as they become stale after the update ^^.
 	bufSliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&mem.Buffer))
 	ce.moduleContext.memorySliceLen = uint64(bufSliceHeader.Len)
 	ce.moduleContext.memoryElement0Address = bufSliceHeader.Data
diff --git a/internal/wasm/jit/jit_amd64.go b/internal/wasm/jit/jit_amd64.go
index 5123b6da..bd2fe8c2 100644
--- a/internal/wasm/jit/jit_amd64.go
+++ b/internal/wasm/jit/jit_amd64.go
@@ -1,5 +1,3 @@
-//go:build amd64
-
 package jit
 
 // This file implements the compiler for amd64/x86_64 target.
@@ -41,13 +39,13 @@ var (
 	float64SignBitMaskAddress                     uintptr
 	float64RestBitMaskAddress                     uintptr
 	float32ForMinimumSigned32bitInteger           float32 = math.Float32frombits(0xCF00_0000)
-	float32ForMinimumSigned32bitIntegerAdddress   uintptr
+	float32ForMinimumSigned32bitIntegerAddress    uintptr
 	float64ForMinimumSigned32bitInteger           float64 = math.Float64frombits(0xC1E0_0000_0020_0000)
-	float64ForMinimumSigned32bitIntegerAdddress   uintptr
+	float64ForMinimumSigned32bitIntegerAddress    uintptr
 	float32ForMinimumSigned64bitInteger           float32 = math.Float32frombits(0xDF00_0000)
-	float32ForMinimumSigned64bitIntegerAdddress   uintptr
+	float32ForMinimumSigned64bitIntegerAddress    uintptr
 	float64ForMinimumSigned64bitInteger           float64 = math.Float64frombits(0xC3E0_0000_0000_0000)
-	float64ForMinimumSigned64bitIntegerAdddress   uintptr
+	float64ForMinimumSigned64bitIntegerAddress    uintptr
 	float32ForMaximumSigned32bitIntPlusOne        float32 = math.Float32frombits(0x4F00_0000)
 	float32ForMaximumSigned32bitIntPlusOneAddress uintptr
 	float64ForMaximumSigned32bitIntPlusOne        float64 = math.Float64frombits(0x41E0_0000_0000_0000)
@@ -66,10 +64,10 @@ func init() {
 	float32RestBitMaskAddress = uintptr(unsafe.Pointer(&float32RestBitMask))
 	float64SignBitMaskAddress = uintptr(unsafe.Pointer(&float64SignBitMask))
 	float64RestBitMaskAddress = uintptr(unsafe.Pointer(&float64RestBitMask))
-	float32ForMinimumSigned32bitIntegerAdddress = uintptr(unsafe.Pointer(&float32ForMinimumSigned32bitInteger))
-	float64ForMinimumSigned32bitIntegerAdddress = uintptr(unsafe.Pointer(&float64ForMinimumSigned32bitInteger))
-	float32ForMinimumSigned64bitIntegerAdddress = uintptr(unsafe.Pointer(&float32ForMinimumSigned64bitInteger))
-	float64ForMinimumSigned64bitIntegerAdddress = uintptr(unsafe.Pointer(&float64ForMinimumSigned64bitInteger))
+	float32ForMinimumSigned32bitIntegerAddress = uintptr(unsafe.Pointer(&float32ForMinimumSigned32bitInteger))
+	float64ForMinimumSigned32bitIntegerAddress = uintptr(unsafe.Pointer(&float64ForMinimumSigned32bitInteger))
+	float32ForMinimumSigned64bitIntegerAddress = uintptr(unsafe.Pointer(&float32ForMinimumSigned64bitInteger))
+	float64ForMinimumSigned64bitIntegerAddress = uintptr(unsafe.Pointer(&float64ForMinimumSigned64bitInteger))
 	float32ForMaximumSigned32bitIntPlusOneAddress = uintptr(unsafe.Pointer(&float32ForMaximumSigned32bitIntPlusOne))
 	float64ForMaximumSigned32bitIntPlusOneAddress = uintptr(unsafe.Pointer(&float64ForMaximumSigned32bitIntPlusOne))
 	float32ForMaximumSigned64bitIntPlusOneAddress = uintptr(unsafe.Pointer(&float32ForMaximumSigned64bitIntPlusOne))
@@ -205,7 +203,7 @@ func (c *amd64Compiler) compile() (code []byte, staticData compiledFunctionStati
 	}
 
 	// Now that the max stack pointer is determined, we are invoking the callback.
-	// Note this MUST be called before Assemble() befolow.
+	// Note this MUST be called before Assemble() below.
 	if c.onStackPointerCeilDeterminedCallBack != nil {
 		c.onStackPointerCeilDeterminedCallBack(stackPointerCeil)
 	}
@@ -234,7 +232,7 @@ func (c *amd64Compiler) compile() (code []byte, staticData compiledFunctionStati
 		for key, l := range c.labels {
 			if len(l.labelBeginningCallbacks) > 0 {
 				// Meaning that some instruction is trying to jump to this label,
-				// but initialStack is not set. There must be a bug at the callsite of br or br_if.
+				// but initialStack is not set. There must be a bug at the call-site of br or br_if.
 				panic(fmt.Sprintf("labelBeginningCallbacks must be called for label %s\n", key))
 			}
 		}
@@ -616,7 +614,7 @@ func (c *amd64Compiler) compileBrIf(o *wazeroir.OperationBrIf) error {
 	c.addInstruction(jmpWithCond)
 	thenTarget, elseTarget := o.Then, o.Else
 
-	// Here's the diagram of how we organize the instructions necessarly for brif operation.
+	// Here's the diagram of how we organize the instructions necessarily for brif operation.
 	//
 	// jmp_with_cond -> jmp (.Else) -> Then operations...
 	//    |---------(satisfied)------------^^^
@@ -857,7 +855,7 @@ func (c *amd64Compiler) compileBrTable(o *wazeroir.OperationBrTable) error {
 				// current implementation.
 				return fmt.Errorf("too large br_table")
 			}
-			// We store the offset from the beiggning of the L0's initial instruction.
+			// We store the offset from the beginning of the L0's initial instruction.
 			binary.LittleEndian.PutUint32(offsetData[i*4:(i+1)*4], uint32(nop.Pc)-uint32(base))
 		}
 		return nil
@@ -924,7 +922,7 @@ func (c *amd64Compiler) compileLabel(o *wazeroir.OperationLabel) (skipLabel bool
 		cb(labelBegin)
 	}
 
-	// Clear for debuggin purpose. See the comment in "len(labelInfo.labelBeginningCallbacks) > 0" block above.
+	// Clear for debugging purpose. See the comment in "len(labelInfo.labelBeginningCallbacks) > 0" block above.
 	labelInfo.labelBeginningCallbacks = nil
 
 	if buildoptions.IsDebugMode {
@@ -1376,7 +1374,7 @@ func (c *amd64Compiler) compileMul(o *wazeroir.OperationMul) (err error) {
 //
 // So, we have to ensure that
 // 1) Previously located value on DX must be saved to memory stack. That is because
-//    the existing value will be overriden after the mul execution.
+//    the existing value will be overridden after the mul execution.
 // 2) One of the operands (x1 or x2) must be on AX register.
 // See https://www.felixcloutier.com/x86/mul#description for detail semantics.
 func (c *amd64Compiler) compileMulForInts(is32Bit bool, mulInstruction obj.As) error {
@@ -1767,7 +1765,7 @@ func (c *amd64Compiler) performDivisionOnInts(isRem, is32Bit, signed bool) error
 		return err
 	}
 
-	// Ensures that previous values on thses registers are saved to memory.
+	// Ensures that previous values on these registers are saved to memory.
 	c.onValueReleaseRegisterToStack(quotientRegister)
 	c.onValueReleaseRegisterToStack(remainderRegister)
 
@@ -1783,7 +1781,7 @@ func (c *amd64Compiler) performDivisionOnInts(isRem, is32Bit, signed bool) error
 	}
 
 	// Now we successfully place x2 on a temp register, so we no longer need to
-	// mark these regiseters used.
+	// mark these registers used.
 	c.locationStack.markRegisterUnused(quotientRegister)
 	c.locationStack.markRegisterUnused(remainderRegister)
 
@@ -1890,7 +1888,7 @@ func (c *amd64Compiler) performDivisionOnInts(isRem, is32Bit, signed bool) error
 		// Set the normal case's jump target.
 		c.addSetJmpOrigins(okJmp)
 	} else if isSignedDiv {
-		// For sigined division, we have to have branches for "math.MinInt{32,64} / -1"
+		// For signed division, we have to have branches for "math.MinInt{32,64} / -1"
 		// case which results in the floating point exception via division error as
 		// the resulting value exceeds the maximum of signed int.
 
@@ -2603,7 +2601,7 @@ func (c *amd64Compiler) compileI32WrapFromI64() error {
 
 // compileITruncFromF implements compiler.compileITruncFromF for the amd64 architecture.
 //
-// Note: in the follwoing implementations, we use CVTSS2SI and CVTSD2SI to convert floats to signed integers.
+// Note: in the following implementation, we use CVTSS2SI and CVTSD2SI to convert floats to signed integers.
 // According to the Intel manual ([1],[2]), if the source float value is either +-Inf or NaN, or it exceeds representative ranges
 // of target signed integer, then the instruction returns "masked" response float32SignBitMask (or float64SignBitMask for 64 bit case).
 // [1] Chapter 11.5.2, SIMD Floating-Point Exception Conditions in "Vol 1, Intel® 64 and IA-32 Architectures Manual"
@@ -2695,7 +2693,7 @@ func (c *amd64Compiler) emitUnsignedI32TruncFromFloat(isFloat32Bit bool) error {
 	jmpIfMinusOrMinusInf.To.Type = obj.TYPE_BRANCH
 	c.addInstruction(jmpIfMinusOrMinusInf)
 
-	// Otherwise, the valus is valid.
+	// Otherwise, the values is valid.
 	okJmpForLessThanMaxInt32PlusOne := c.newProg()
 	okJmpForLessThanMaxInt32PlusOne.As = obj.AJMP
 	okJmpForLessThanMaxInt32PlusOne.To.Type = obj.TYPE_BRANCH
@@ -2845,7 +2843,7 @@ func (c *amd64Compiler) emitUnsignedI64TruncFromFloat(isFloat32Bit bool) error {
 	jmpIfMinusOrMinusInf.To.Type = obj.TYPE_BRANCH
 	c.addInstruction(jmpIfMinusOrMinusInf)
 
-	// Otherwise, the valus is valid.
+	// Otherwise, the values is valid.
 	okJmpForLessThanMaxInt64PlusOne := c.newProg()
 	okJmpForLessThanMaxInt64PlusOne.As = obj.AJMP
 	okJmpForLessThanMaxInt64PlusOne.To.Type = obj.TYPE_BRANCH
@@ -2957,8 +2955,8 @@ func (c *amd64Compiler) emitSignedI32TruncFromFloat(isFloat32Bit bool) error {
 
 	// We compare the conversion result with the sign bit mask to check if it is either
 	// 1) the source float value is either +-Inf or NaN, or it exceeds representative ranges of 32bit signed integer, or
-	// 2) the source equals the minimum signed 32-bit (=-2147483648.000000) whose bit pattern is float32ForMinimumSigned32bitIntegerAdddress for 32 bit flaot
-	// 	  or float64ForMinimumSigned32bitIntegerAdddress for 64bit float.
+	// 2) the source equals the minimum signed 32-bit (=-2147483648.000000) whose bit pattern is float32ForMinimumSigned32bitIntegerAddress for 32 bit float
+	// 	  or float64ForMinimumSigned32bitIntegerAddress for 64bit float.
 	cmpResult := c.newProg()
 	cmpResult.As = x86.ACMPL
 	cmpResult.From.Type = obj.TYPE_MEM
@@ -3002,10 +3000,10 @@ func (c *amd64Compiler) emitSignedI32TruncFromFloat(isFloat32Bit bool) error {
 	jmpIfNotNaN.To.SetTarget(checkIfExceedsLowerBound)
 	if isFloat32Bit {
 		checkIfExceedsLowerBound.As = x86.AUCOMISS
-		checkIfExceedsLowerBound.From.Offset = int64(float32ForMinimumSigned32bitIntegerAdddress)
+		checkIfExceedsLowerBound.From.Offset = int64(float32ForMinimumSigned32bitIntegerAddress)
 	} else {
 		checkIfExceedsLowerBound.As = x86.AUCOMISD
-		checkIfExceedsLowerBound.From.Offset = int64(float64ForMinimumSigned32bitIntegerAdddress)
+		checkIfExceedsLowerBound.From.Offset = int64(float64ForMinimumSigned32bitIntegerAddress)
 	}
 	checkIfExceedsLowerBound.From.Type = obj.TYPE_MEM
 	checkIfExceedsLowerBound.To.Type = obj.TYPE_REG
@@ -3082,8 +3080,8 @@ func (c *amd64Compiler) emitSignedI64TruncFromFloat(isFloat32Bit bool) error {
 
 	// We compare the conversion result with the sign bit mask to check if it is either
 	// 1) the source float value is either +-Inf or NaN, or it exceeds representative ranges of 32bit signed integer, or
-	// 2) the source equals the minimum signed 32-bit (=-9223372036854775808.0) whose bit pattern is float32ForMinimumSigned64bitIntegerAdddress for 32 bit flaot
-	// 	  or float64ForMinimumSigned64bitIntegerAdddress for 64bit float.
+	// 2) the source equals the minimum signed 32-bit (=-9223372036854775808.0) whose bit pattern is float32ForMinimumSigned64bitIntegerAddress for 32 bit float
+	// 	  or float64ForMinimumSigned64bitIntegerAddress for 64bit float.
 	cmpResult := c.newProg()
 	cmpResult.As = x86.ACMPQ
 	cmpResult.From.Type = obj.TYPE_MEM
@@ -3126,10 +3124,10 @@ func (c *amd64Compiler) emitSignedI64TruncFromFloat(isFloat32Bit bool) error {
 	jmpIfNotNaN.To.SetTarget(checkIfExceedsLowerBound)
 	if isFloat32Bit {
 		checkIfExceedsLowerBound.As = x86.AUCOMISS
-		checkIfExceedsLowerBound.From.Offset = int64(float32ForMinimumSigned64bitIntegerAdddress)
+		checkIfExceedsLowerBound.From.Offset = int64(float32ForMinimumSigned64bitIntegerAddress)
 	} else {
 		checkIfExceedsLowerBound.As = x86.AUCOMISD
-		checkIfExceedsLowerBound.From.Offset = int64(float64ForMinimumSigned64bitIntegerAdddress)
+		checkIfExceedsLowerBound.From.Offset = int64(float64ForMinimumSigned64bitIntegerAddress)
 	}
 	checkIfExceedsLowerBound.From.Type = obj.TYPE_MEM
 	checkIfExceedsLowerBound.To.Type = obj.TYPE_REG
@@ -4465,7 +4463,7 @@ func (c *amd64Compiler) moveStackToRegister(loc *valueLocation) {
 
 // maybeMoveTopConditionalToFreeGeneralPurposeRegister moves the top value on the stack
 // if the value is located on a conditional register. This is usually called at the beginning of
-// amd64Compiler.compile* functions where we possibly emit istructions without saving the conditional
+// amd64Compiler.compile* functions where we possibly emit instructions without saving the conditional
 // register value. The compile* functions without calling this function is saving the conditional
 // value to the stack or register by invoking ensureOnGeneralPurposeRegister for the top.
 func (c *amd64Compiler) maybeMoveTopConditionalToFreeGeneralPurposeRegister() (err error) {
@@ -4652,8 +4650,8 @@ func (c *amd64Compiler) callFunction(index wasm.Index, compiledFunctionAddressRe
 
 	// Otherwise, we have to make the builtin function call to grow the call frame stack.
 	if !isNilRegister(compiledFunctionAddressRegister) {
-		// If we need to get the target funcaddr from register (call_indirect case), we must save it before growing callframe stack,
-		// as the register is not saved across function calls.
+		// If we need to get the target funcaddr from register (call_indirect case), we must save it before growing the
+		// call-frame stack, as the register is not saved across function calls.
 		savedOffsetLocation := c.locationStack.pushValueLocationOnRegister(compiledFunctionAddressRegister)
 		c.releaseRegisterToStack(savedOffsetLocation)
 	}
@@ -4677,7 +4675,7 @@ func (c *amd64Compiler) callFunction(index wasm.Index, compiledFunctionAddressRe
 	// Also we have to re-read the call frame stack pointer into callFrameStackPointerRegister.
 	c.getCallFrameStackPointer(callFrameStackPointerRegister)
 
-	// Now that callframe stack is enough length, we are ready to create a new call frame
+	// Now that call-frame stack is enough length, we are ready to create a new call frame
 	// for the function call we are about to make.
 	getCallFrameStackElement0Address := c.newProg()
 	jmpIfNotCallFrameStackNeedsGrow.To.SetTarget(getCallFrameStackElement0Address)
@@ -4789,19 +4787,19 @@ func (c *amd64Compiler) callFunction(index wasm.Index, compiledFunctionAddressRe
 	// 3) Set rc.next to specify which function is executed on the current call frame (needs to make builtin function calls).
 	{
 		if isNilRegister(compiledFunctionAddressRegister) {
-			// We must set the target function's address(pointer) of *compiledFunction into the next callframe stack.
+			// We must set the target function's address(pointer) of *compiledFunction into the next call-frame stack.
 			// In the example, this is equivalent to writing the value into "rc.next".
 			//
 			// First, we read the address of the first item of callEngine.compiledFunctions slice (= &callEngine.compiledFunctions[0])
 			// into tmpRegister.
-			readCopmiledFunctionsElement0Address := c.newProg()
-			readCopmiledFunctionsElement0Address.As = x86.AMOVQ
-			readCopmiledFunctionsElement0Address.To.Type = obj.TYPE_REG
-			readCopmiledFunctionsElement0Address.To.Reg = tmpRegister
-			readCopmiledFunctionsElement0Address.From.Type = obj.TYPE_MEM
-			readCopmiledFunctionsElement0Address.From.Reg = reservedRegisterForCallEngine
-			readCopmiledFunctionsElement0Address.From.Offset = callEngineModuleContextCompiledFunctionsElement0AddressOffset
-			c.addInstruction(readCopmiledFunctionsElement0Address)
+			readCompiledFunctionsElement0Address := c.newProg()
+			readCompiledFunctionsElement0Address.As = x86.AMOVQ
+			readCompiledFunctionsElement0Address.To.Type = obj.TYPE_REG
+			readCompiledFunctionsElement0Address.To.Reg = tmpRegister
+			readCompiledFunctionsElement0Address.From.Type = obj.TYPE_MEM
+			readCompiledFunctionsElement0Address.From.Reg = reservedRegisterForCallEngine
+			readCompiledFunctionsElement0Address.From.Offset = callEngineModuleContextCompiledFunctionsElement0AddressOffset
+			c.addInstruction(readCompiledFunctionsElement0Address)
 
 			// Next, read the address of the target function (= &callEngine.compiledFunctions[offset])
 			// into targetAddressRegister.
@@ -4818,7 +4816,7 @@ func (c *amd64Compiler) callFunction(index wasm.Index, compiledFunctionAddressRe
 		} else {
 			targetAddressRegister = compiledFunctionAddressRegister
 		}
-		// Finally, we are ready to place the address of the target function's *compiledFunction into the new callframe.
+		// Finally, we are ready to place the address of the target function's *compiledFunction into the new call-frame.
 		// In the example, this is equivalent to set "rc.next".
 		putCompiledFunctionFunctionIndexOnNewCallFrame := c.newProg()
 		putCompiledFunctionFunctionIndexOnNewCallFrame.As = x86.AMOVQ
@@ -4848,7 +4846,7 @@ func (c *amd64Compiler) callFunction(index wasm.Index, compiledFunctionAddressRe
 	setReturnAddress.From.Reg = tmpRegister
 	c.addInstruction(setReturnAddress)
 
-	// Every preparetion (1 to 5 in the description above) is done to enter into the target function.
+	// Every preparation (1 to 5 in the description above) is done to enter into the target function.
 	// So we increment the call frame stack pointer.
 	incCallFrameStackPointer := c.newProg()
 	incCallFrameStackPointer.As = x86.AINCQ
@@ -4876,7 +4874,7 @@ func (c *amd64Compiler) callFunction(index wasm.Index, compiledFunctionAddressRe
 	// Due to the change to callEngine.valueStackContext.stackBasePointer.
 	c.initializeReservedStackBasePointer()
 	// Due to the change to callEngine.moduleContext.moduleInstanceAddress.
-	if err := c.initializeModuleContext(); err != nil {
+	if err := c.compileModuleContextInitialization(); err != nil {
 		return err
 	}
 	// Due to the change to callEngine.moduleContext.moduleInstanceAddress as that might result in
@@ -5140,7 +5138,7 @@ func (c *amd64Compiler) callGoFunction(jitStatus jitCallStatusCode, index wasm.I
 
 // readInstructionAddress add a LEA instruction to read the target instruction's absolute address into the destinationRegister.
 // beforeAcquisitionTargetInstruction is the instruction kind (e.g. RET, JMP, etc.) right before the instruction
-// of which the callsite wants to aquire the absolute address.
+// of which the call-site wants to acquire the absolute address.
 func (c *amd64Compiler) readInstructionAddress(destinationRegister int16, beforeAcquisitionTargetInstruction obj.As) {
 	// Emit the instruction in the form of "LEA destination [RIP + offset]".
 	readInstructionAddress := c.newProg()
@@ -5163,7 +5161,7 @@ func (c *amd64Compiler) readInstructionAddress(destinationRegister int16, before
 		// right after LEA because RIP points to that next instruction in LEA instruction.
 		base := readInstructionAddress.Link
 
-		// Find the address aquisition target instruction.
+		// Find the address acquisition target instruction.
 		target := base
 		for target != nil {
 			// Advance until we have the target.As has the given instruction kind.
@@ -5269,7 +5267,7 @@ func (c *amd64Compiler) compilePreamble() (err error) {
 
 	// Once the stack base pointer is initialized and the size of stack is ok,
 	// initialize the module context next.
-	if err := c.initializeModuleContext(); err != nil {
+	if err := c.compileModuleContextInitialization(); err != nil {
 		return err
 	}
 
@@ -5359,13 +5357,13 @@ func (c *amd64Compiler) maybeGrowValueStack() error {
 	subStackBasePointer.From.Offset = callEngineValueStackContextStackBasePointerOffset
 	c.addInstruction(subStackBasePointer)
 
-	// If stack base pointer + max stack poitner > valueStackLen, we need to grow the stack.
+	// If stack base pointer + max stack pointer > valueStackLen, we need to grow the stack.
 	cmpWithStackPointerCeil := c.newProg()
 	cmpWithStackPointerCeil.As = x86.ACMPQ
 	cmpWithStackPointerCeil.From.Type = obj.TYPE_REG
 	cmpWithStackPointerCeil.From.Reg = tmpRegister
 	cmpWithStackPointerCeil.To.Type = obj.TYPE_CONST
-	// We don't yet know the max stack poitner at this point.
+	// We don't yet know the max stack pointer at this point.
 	// The max stack pointer is determined after emitting all the instructions.
 	c.onStackPointerCeilDeterminedCallBack = func(stackPointerCeil uint64) { cmpWithStackPointerCeil.To.Offset = int64(stackPointerCeil) }
 	c.addInstruction(cmpWithStackPointerCeil)
@@ -5385,10 +5383,10 @@ func (c *amd64Compiler) maybeGrowValueStack() error {
 	return nil
 }
 
-// initializeModuleContext adds instruction to initialize callEngine.ModuleContext's fields based on
+// compileModuleContextInitialization adds instructions to initialize callEngine.ModuleContext's fields based on
 // callEngine.ModuleContext.ModuleInstanceAddress.
 // This is called in two cases: in function preamble, and on the return from (non-Go) function calls.
-func (c *amd64Compiler) initializeModuleContext() error {
+func (c *amd64Compiler) compileModuleContextInitialization() error {
 
 	// Obtain the temporary registers to be used in the followings.
 	regs, found := c.locationStack.takeFreeRegisters(generalPurposeRegisterTypeInt, 3)
@@ -5589,7 +5587,7 @@ func (c *amd64Compiler) initializeModuleContext() error {
 	{
 		// "tmpRegister = [moduleInstanceAddressRegister + moduleInstanceEngineOffset + interfaceDataOffset] (== *moduleEngine)"
 		//
-		// Go's interface is layed out on memory as two quad words as struct {tab, data uintptr}
+		// Go's interface is laid out on memory as two quad words as struct {tab, data uintptr}
 		// where tab points to the interface table, and the latter points to the actual
 		// implementation of interface. This case, we extract "data" pointer as *moduleEngine.
 		// See the following references for detail:
@@ -5615,14 +5613,14 @@ func (c *amd64Compiler) initializeModuleContext() error {
 		c.addInstruction(readCompiledFunctionsElement0Address)
 
 		// "callEngine.moduleContext.compiledFunctionsElement0Address = tmpRegister".
-		writeCompiledFunctionsElement0AddresssIntoCallEngine := c.newProg()
-		writeCompiledFunctionsElement0AddresssIntoCallEngine.As = x86.AMOVQ
-		writeCompiledFunctionsElement0AddresssIntoCallEngine.To.Type = obj.TYPE_MEM
-		writeCompiledFunctionsElement0AddresssIntoCallEngine.To.Reg = reservedRegisterForCallEngine
-		writeCompiledFunctionsElement0AddresssIntoCallEngine.To.Offset = callEngineModuleContextCompiledFunctionsElement0AddressOffset
-		writeCompiledFunctionsElement0AddresssIntoCallEngine.From.Type = obj.TYPE_REG
-		writeCompiledFunctionsElement0AddresssIntoCallEngine.From.Reg = tmpRegister
-		c.addInstruction(writeCompiledFunctionsElement0AddresssIntoCallEngine)
+		writeCompiledFunctionsElement0AddressIntoCallEngine := c.newProg()
+		writeCompiledFunctionsElement0AddressIntoCallEngine.As = x86.AMOVQ
+		writeCompiledFunctionsElement0AddressIntoCallEngine.To.Type = obj.TYPE_MEM
+		writeCompiledFunctionsElement0AddressIntoCallEngine.To.Reg = reservedRegisterForCallEngine
+		writeCompiledFunctionsElement0AddressIntoCallEngine.To.Offset = callEngineModuleContextCompiledFunctionsElement0AddressOffset
+		writeCompiledFunctionsElement0AddressIntoCallEngine.From.Type = obj.TYPE_REG
+		writeCompiledFunctionsElement0AddressIntoCallEngine.From.Reg = tmpRegister
+		c.addInstruction(writeCompiledFunctionsElement0AddressIntoCallEngine)
 	}
 
 	c.locationStack.markRegisterUnused(regs...)
diff --git a/internal/wasm/jit/jit_arm64.go b/internal/wasm/jit/jit_arm64.go
index a27160b3..bc7718de 100644
--- a/internal/wasm/jit/jit_arm64.go
+++ b/internal/wasm/jit/jit_arm64.go
@@ -1,5 +1,3 @@
-//go:build arm64
-
 // This file implements the compiler for arm64 target.
 // Please refer to https://developer.arm.com/documentation/102374/latest/
 // if unfamiliar with arm64 instructions and semantics.
@@ -42,7 +40,7 @@ type archContext struct {
 	// Note: this is only used by JIT code so mark this as nolint.
 	jitCallReturnAddress uint64 //nolint
 
-	// Loading large constants in arm64 is a bit costly so we place the following
+	// Loading large constants in arm64 is a bit costly, so we place the following
 	// consts on callEngine struct so that we can quickly access them during various operations.
 
 	// minimum32BitSignedInt is used for overflow check for 32-bit signed division.
@@ -141,7 +139,7 @@ func (c *arm64Compiler) compile() (code []byte, staticData compiledFunctionStati
 	}
 
 	// Now that the ceil of stack pointer is determined, we are invoking the callback.
-	// Note: this must be called before Assemble() befolow.
+	// Note: this must be called before Assemble() below.
 	if c.onStackPointerCeilDeterminedCallBack != nil {
 		c.onStackPointerCeilDeterminedCallBack(stackPointerCeil)
 	}
@@ -364,7 +362,7 @@ func (c *arm64Compiler) compileRegisterAndConstSourceToNoneInstruction(instructi
 	c.addInstruction(inst)
 }
 
-func (c *arm64Compiler) compilelBranchInstruction(inst obj.As) (br *obj.Prog) {
+func (c *arm64Compiler) compileBranchInstruction(inst obj.As) (br *obj.Prog) {
 	br = c.newProg()
 	br.As = inst
 	br.To.Type = obj.TYPE_BRANCH
@@ -480,14 +478,14 @@ func (c *arm64Compiler) compileMaybeGrowValueStack() error {
 		tmpY,
 	)
 	// At this point of compilation, we don't know the value of stack point ceil,
-	// so we layzily resolve the value later.
+	// so we lazily resolve the value later.
 	c.onStackPointerCeilDeterminedCallBack = func(stackPointerCeil uint64) { loadStackPointerCeil.From.Offset = int64(stackPointerCeil) }
 
 	// Compare tmpX (len(ce.valueStack) - ce.stackBasePointer) and tmpY (ce.stackPointerCeil)
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMP, tmpX, tmpY)
 
 	// If ceil > valueStackLen - stack base pointer, we need to grow the stack by calling builtin Go function.
-	brIfValueStackOK := c.compilelBranchInstruction(arm64.ABLS)
+	brIfValueStackOK := c.compileBranchInstruction(arm64.ABLS)
 	if err := c.compileCallGoFunction(jitCallStatusCodeCallBuiltInFunction, builtinFunctionIndexGrowValueStack); err != nil {
 		return err
 	}
@@ -516,7 +514,7 @@ func (c *arm64Compiler) compileReturnFunction() error {
 	// Alias for readability.
 	callFramePointerReg, callFrameStackTopAddressRegister, tmpReg := tmpRegs[0], tmpRegs[1], tmpRegs[2]
 
-	// First we decrement the callframe stack pointer.
+	// First we decrement the call-frame stack pointer.
 	c.compileMemoryToRegisterInstruction(arm64.AMOVD, reservedRegisterForCallEngine, callEngineGlobalContextCallFrameStackPointerOffset, callFramePointerReg)
 	c.compileConstToRegisterInstruction(arm64.ASUBS, 1, callFramePointerReg)
 	c.compileRegisterToMemoryInstruction(arm64.AMOVD, callFramePointerReg, reservedRegisterForCallEngine, callEngineGlobalContextCallFrameStackPointerOffset)
@@ -525,7 +523,7 @@ func (c *arm64Compiler) compileReturnFunction() error {
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMP, callFramePointerReg, zeroRegister)
 
 	// If the values are identical, we return back to the Go code with returned status.
-	brIfNotEqual := c.compilelBranchInstruction(arm64.ABNE)
+	brIfNotEqual := c.compileBranchInstruction(arm64.ABNE)
 	if err := c.compileExitFromNativeCode(jitCallStatusCodeReturned); err != nil {
 		return err
 	}
@@ -533,7 +531,7 @@ func (c *arm64Compiler) compileReturnFunction() error {
 	// Otherwise, we have to jump to the caller's return address.
 	c.setBranchTargetOnNext(brIfNotEqual)
 
-	// First, we have to calculate the caller callFrame's absolute address to aquire the return address.
+	// First, we have to calculate the caller callFrame's absolute address to acquire the return address.
 	//
 	// "tmpReg = &ce.callFrameStack[0]"
 	c.compileMemoryToRegisterInstruction(arm64.AMOVD,
@@ -825,7 +823,7 @@ func (c *arm64Compiler) compileBrIf(o *wazeroir.OperationBrIf) error {
 	conditionalBR := c.newProg()
 	conditionalBR.To.Type = obj.TYPE_BRANCH
 	if cond.onConditionalRegister() {
-		// If the cond is on a conditional register, it corresponds to one of "conditonal codes"
+		// If the cond is on a conditional register, it corresponds to one of "conditional codes"
 		// https://developer.arm.com/documentation/dui0801/a/Condition-Codes/Condition-code-suffixes
 		// Here we represent the conditional codes by using arm64.COND_** registers, and that means the
 		// conditional jump can be performed if we use arm64.AB**.
@@ -861,7 +859,7 @@ func (c *arm64Compiler) compileBrIf(o *wazeroir.OperationBrIf) error {
 		}
 	} else {
 		// If the value is not on the conditional register, we compare the value with the zero register,
-		// and then do the conditional BR if the value does't equal zero.
+		// and then do the conditional BR if the value doesn't equal zero.
 		if err := c.compileEnsureOnGeneralPurposeRegister(cond); err != nil {
 			return err
 		}
@@ -888,7 +886,7 @@ func (c *arm64Compiler) compileBrIf(o *wazeroir.OperationBrIf) error {
 	}
 
 	// Now ready to emit the code for branching into then branch.
-	// Retrieve the original value location stack so that the code below wont'be affected by the Else branch ^^.
+	// Retrieve the original value location stack so that the code below won't be affected by the Else branch ^^.
 	c.setLocationStack(saved)
 	// We branch into here from the original conditional BR (conditionalBR).
 	c.setBranchTargetOnNext(conditionalBR)
@@ -919,7 +917,7 @@ func (c *arm64Compiler) compileBranchInto(target *wazeroir.BranchTarget) error {
 			targetLabel.initialStack = c.locationStack.clone()
 		}
 
-		br := c.compilelBranchInstruction(obj.AJMP)
+		br := c.compileBranchInstruction(obj.AJMP)
 		c.assignBranchTarget(labelKey, br)
 		return nil
 	}
@@ -978,10 +976,10 @@ func (c *arm64Compiler) compileBrTable(o *wazeroir.OperationBrTable) error {
 	// Load the branch table's length.
 	// "tmpReg = len(o.Targets)"
 	c.compileConstToRegisterInstruction(arm64.AMOVW, int64(len(o.Targets)), tmpReg)
-	// Compare the length with offest.
+	// Compare the length with offset.
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMPW, tmpReg, index.register)
 	// If the value exceeds the length, we will branch into the default target (corresponding to len(o.Targets) index).
-	brDefaultIndex := c.compilelBranchInstruction(arm64.ABLO)
+	brDefaultIndex := c.compileBranchInstruction(arm64.ABLO)
 	c.compileRegisterToRegisterInstruction(arm64.AMOVW, tmpReg, index.register)
 	c.setBranchTargetOnNext(brDefaultIndex)
 
@@ -1024,7 +1022,7 @@ func (c *arm64Compiler) compileBrTable(o *wazeroir.OperationBrTable) error {
 	// "index.register = tmpReg + (index.register << 2) (== &offsetData[offset])"
 	c.compileAddInstructionWithLeftShiftedRegister(index.register, 2, tmpReg, index.register)
 
-	// "index.regsetr = *index.reigier (== offsetData[offset])"
+	// "index.register = *index.register (== offsetData[offset])"
 	c.compileMemoryToRegisterInstruction(arm64.AMOVW, index.register, 0, index.register)
 
 	// Now we read the address of the beginning of the jump table.
@@ -1084,7 +1082,7 @@ func (c *arm64Compiler) compileBrTable(o *wazeroir.OperationBrTable) error {
 				// current implementation.
 				return fmt.Errorf("too large br_table")
 			}
-			// We store the offset from the beiggning of the L0's initial instruction.
+			// We store the offset from the beginning of the L0's initial instruction.
 			binary.LittleEndian.PutUint32(offsetData[i*4:(i+1)*4], uint32(nop.Pc)-uint32(base))
 		}
 		return nil
@@ -1129,13 +1127,13 @@ func (c *arm64Compiler) compileCallImpl(index wasm.Index, compiledFunctionAddres
 	)
 	// Compare tmp(len(ce.callFrameStack)) with callFrameStackPointerRegister(ce.callFrameStackPointer).
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMP, tmp, callFrameStackPointerRegister)
-	brIfCallFrameStackOK := c.compilelBranchInstruction(arm64.ABNE)
+	brIfCallFrameStackOK := c.compileBranchInstruction(arm64.ABNE)
 
 	// If these values equal, we need to grow the callFrame stack.
 	// For call_indirect, we need to push the value back to the register.
 	if !isNilRegister(compiledFunctionAddressRegister) {
-		// If we need to get the target funcaddr from register (call_indirect case), we must save it before growing callframe stack,
-		// as the register is not saved across function calls.
+		// If we need to get the target funcaddr from register (call_indirect case), we must save it before growing the
+		// call-frame stack, as the register is not saved across function calls.
 		savedOffsetLocation := c.locationStack.pushValueLocationOnRegister(compiledFunctionAddressRegister)
 		if err := c.compileReleaseRegisterToStack(savedOffsetLocation); err != nil {
 			return err
@@ -1230,7 +1228,7 @@ func (c *arm64Compiler) compileCallImpl(index wasm.Index, compiledFunctionAddres
 		compiledFunctionRegister = compiledFunctionAddressRegister
 	}
 
-	// Finally, we are ready to write the address of the target function's *compiledFunction into the new callframe.
+	// Finally, we are ready to write the address of the target function's *compiledFunction into the new call-frame.
 	c.compileRegisterToMemoryInstruction(arm64.AMOVD,
 		compiledFunctionRegister,
 		callFrameStackTopAddressRegister, callFrameCompiledFunctionOffset)
@@ -1239,15 +1237,14 @@ func (c *arm64Compiler) compileCallImpl(index wasm.Index, compiledFunctionAddres
 	//
 	// First, Get the return address into the tmp.
 	c.compileReadInstructionAddress(obj.AJMP, tmp)
-	// Then write the address into the callframe.
+	// Then write the address into the call-frame.
 	c.compileRegisterToMemoryInstruction(arm64.AMOVD,
 		tmp,
 		// "ra.current" is BELOW the top address. See the above example for detail.
 		callFrameStackTopAddressRegister, -(callFrameDataSize - callFrameReturnAddressOffset),
 	)
 
-	// Everthing is done to make function call now.
-	// We increment the callframe stack pointer.
+	// Everything is done to make function call now: increment the call-frame stack pointer.
 	c.compileMemoryToRegisterInstruction(arm64.AMOVD,
 		reservedRegisterForCallEngine, callEngineGlobalContextCallFrameStackPointerOffset,
 		tmp)
@@ -1406,7 +1403,7 @@ func (c *arm64Compiler) compileCallIndirect(o *wazeroir.OperationCallIndirect) e
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMP, tmp, offset.register)
 
 	// If it exceeds len(table), we exit the execution.
-	brIfOffsetOK := c.compilelBranchInstruction(arm64.ABLO)
+	brIfOffsetOK := c.compileBranchInstruction(arm64.ABLO)
 	if err := c.compileExitFromNativeCode(jitCallStatusCodeInvalidTableAccess); err != nil {
 		return err
 	}
@@ -1422,7 +1419,7 @@ func (c *arm64Compiler) compileCallIndirect(o *wazeroir.OperationCallIndirect) e
 		tmp,
 	)
 	// "offset = tmp + (offset << 3) (== &table[offset])"
-	// Here we left shiting by 3 in order to get the offset in bytes,
+	// Here we left shifting by 3 in order to get the offset in bytes,
 	// and the table element type is uintptr which is 8 bytes.
 	c.compileAddInstructionWithLeftShiftedRegister(
 		offset.register, 3,
@@ -1435,11 +1432,11 @@ func (c *arm64Compiler) compileCallIndirect(o *wazeroir.OperationCallIndirect) e
 
 	// Check if the value of table[offset] equals zero, meaning that the target element is uninitialized.
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMP, zeroRegister, offset.register)
-	brIfInitizlied := c.compilelBranchInstruction(arm64.ABNE)
+	brIfInitialized := c.compileBranchInstruction(arm64.ABNE)
 	if err := c.compileExitFromNativeCode(jitCallStatusCodeInvalidTableAccess); err != nil {
 		return err
 	}
-	c.setBranchTargetOnNext(brIfInitizlied)
+	c.setBranchTargetOnNext(brIfInitialized)
 
 	targetFunctionType := c.f.Module.Types[o.TypeIndex]
 	// Next we check the type matches, i.e. table[offset].source.TypeID == targetFunctionType.
@@ -1459,7 +1456,7 @@ func (c *arm64Compiler) compileCallIndirect(o *wazeroir.OperationCallIndirect) e
 
 	// Compare these two values, and if they equal, we are ready to make function call.
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMPW, tmp, reservedRegisterForTemporary)
-	brIfTypeMatched := c.compilelBranchInstruction(arm64.ABEQ)
+	brIfTypeMatched := c.compileBranchInstruction(arm64.ABEQ)
 	if err := c.compileExitFromNativeCode(jitCallStatusCodeTypeMismatchOnIndirectCall); err != nil {
 		return err
 	}
@@ -1505,7 +1502,7 @@ func (c *arm64Compiler) compileDropRange(r *wazeroir.InclusiveRange) error {
 	// Note: drop target range is inclusive.
 	dropNum := r.End - r.Start + 1
 
-	// Then mark all registers used by drop tragets unused.
+	// Then mark all registers used by drop targets unused.
 	for i := 0; i < dropNum; i++ {
 		if loc := c.locationStack.pop(); loc.onRegister() {
 			c.markRegisterUnused(loc.register)
@@ -1514,8 +1511,8 @@ func (c *arm64Compiler) compileDropRange(r *wazeroir.InclusiveRange) error {
 
 	for _, live := range liveValues {
 		// If the value is on a memory, we have to move it to a register,
-		// otherwise the memory location is overriden by other values
-		// after this drop instructin.
+		// otherwise the memory location is overridden by other values
+		// after this drop instruction.
 		if err := c.compileEnsureOnGeneralPurposeRegister(live); err != nil {
 			return err
 		}
@@ -1547,13 +1544,13 @@ func (c *arm64Compiler) compileSelect() error {
 	}
 
 	// In the following, we emit the code so that x1's register contains the chosen value
-	// no matter which of oroginal x1 or x2 is selected.
+	// no matter which of original x1 or x2 is selected.
 	//
 	// If x1 is currently on zero register, we cannot place the result because
 	// "MOV zeroRegister x2.register" results in zeroRegister regardless of the value.
-	// So we explicitly assign a general purpuse register to x1 here.
+	// So we explicitly assign a general purpose register to x1 here.
 	if isZeroRegister(x1.register) {
-		// Mark x2 and cv's regiseters are used so they won't be chosen.
+		// Mark x2 and cv's registers are used so they won't be chosen.
 		c.markRegisterUsed(x2.register)
 		// Pick the non-zero register for x1.
 		x1Reg, err := c.allocateRegister(generalPurposeRegisterTypeInt)
@@ -1565,10 +1562,10 @@ func (c *arm64Compiler) compileSelect() error {
 		c.compileRegisterToRegisterInstruction(arm64.AMOVD, zeroRegister, x1Reg)
 	}
 
-	// At this point, x1 is non-zero register, and x2 is either general purpuse or zero register.
+	// At this point, x1 is non-zero register, and x2 is either general purpose or zero register.
 
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMPW, zeroRegister, cv.register)
-	brIfNotZero := c.compilelBranchInstruction(arm64.ABNE)
+	brIfNotZero := c.compileBranchInstruction(arm64.ABNE)
 	c.addInstruction(brIfNotZero)
 
 	// If cv == 0, we move the value of x2 to the x1.register.
@@ -1629,7 +1626,7 @@ func (c *arm64Compiler) compileAdd(o *wazeroir.OperationAdd) error {
 		return err
 	}
 
-	// Additon can be nop if one of operands is zero.
+	// Addition can be nop if one of operands is zero.
 	if isZeroRegister(x1.register) {
 		c.locationStack.pushValueLocationOnRegister(x2.register)
 		return nil
@@ -1700,7 +1697,7 @@ func (c *arm64Compiler) compileMul(o *wazeroir.OperationMul) error {
 		return err
 	}
 
-	// Multiplcation can be done by putting a zero register if one of operands is zero.
+	// Multiplication can be done by putting a zero register if one of operands is zero.
 	if isZeroRegister(x1.register) || isZeroRegister(x2.register) {
 		c.locationStack.pushValueLocationOnRegister(zeroRegister)
 		return nil
@@ -1885,7 +1882,7 @@ func (c *arm64Compiler) compileDiv(o *wazeroir.OperationDiv) error {
 }
 
 // compileIntegerDivPrecheck adds instructions to check if the divisor and dividend are sound for division operation.
-// First, this adds instrucitons to check if the divisor equals zero, and if so, exits the function.
+// First, this adds instructions to check if the divisor equals zero, and if so, exits the function.
 // Plus, for signed divisions, check if the result might result in overflow or not.
 func (c *arm64Compiler) compileIntegerDivPrecheck(is32Bit, isSigned bool, dividend, divisor int16) error {
 	// We check the divisor value equals zero.
@@ -1903,7 +1900,7 @@ func (c *arm64Compiler) compileIntegerDivPrecheck(is32Bit, isSigned bool, divide
 	c.compileTwoRegistersToNoneInstruction(cmpInst, zeroRegister, divisor)
 
 	// If it is zero, we exit with jitCallStatusIntegerDivisionByZero.
-	brIfDivisorNonZero := c.compilelBranchInstruction(arm64.ABNE)
+	brIfDivisorNonZero := c.compileBranchInstruction(arm64.ABNE)
 	if err := c.compileExitFromNativeCode(jitCallStatusIntegerDivisionByZero); err != nil {
 		return err
 	}
@@ -1913,7 +1910,7 @@ func (c *arm64Compiler) compileIntegerDivPrecheck(is32Bit, isSigned bool, divide
 
 	// If the operation is a signed integer div, we have to do an additional check on overflow.
 	if isSigned {
-		// For sigined division, we have to have branches for "math.MinInt{32,64} / -1"
+		// For signed division, we have to have branches for "math.MinInt{32,64} / -1"
 		// case which results in the overflow.
 
 		// First, we compare the divisor with -1.
@@ -1921,7 +1918,7 @@ func (c *arm64Compiler) compileIntegerDivPrecheck(is32Bit, isSigned bool, divide
 		c.compileTwoRegistersToNoneInstruction(cmpInst, reservedRegisterForTemporary, divisor)
 
 		// If they not equal, we skip the following check.
-		brIfDivisorNonMinusOne := c.compilelBranchInstruction(arm64.ABNE)
+		brIfDivisorNonMinusOne := c.compileBranchInstruction(arm64.ABNE)
 
 		// Otherwise, we further check if the dividend equals math.MinInt32 or MinInt64.
 		c.compileMemoryToRegisterInstruction(
@@ -1932,7 +1929,7 @@ func (c *arm64Compiler) compileIntegerDivPrecheck(is32Bit, isSigned bool, divide
 		c.compileTwoRegistersToNoneInstruction(cmpInst, reservedRegisterForTemporary, dividend)
 
 		// If they not equal, we are safe to execute the division.
-		brIfDividendNotMinInt := c.compilelBranchInstruction(arm64.ABNE)
+		brIfDividendNotMinInt := c.compileBranchInstruction(arm64.ABNE)
 
 		// Otherwise, we raise overflow error.
 		if err := c.compileExitFromNativeCode(jitCallStatusIntegerOverflow); err != nil {
@@ -1985,12 +1982,12 @@ func (c *arm64Compiler) compileRem(o *wazeroir.OperationRem) error {
 	c.compileTwoRegistersToNoneInstruction(cmpInst, zeroRegister, divisorReg)
 
 	// If it is zero, we exit with jitCallStatusIntegerDivisionByZero.
-	brIfDivisorNonZero := c.compilelBranchInstruction(arm64.ABNE)
+	brIfDivisorNonZero := c.compileBranchInstruction(arm64.ABNE)
 	if err := c.compileExitFromNativeCode(jitCallStatusIntegerDivisionByZero); err != nil {
 		return err
 	}
 
-	// Othrewise, we proceed.
+	// Otherwise, we proceed.
 	c.setBranchTargetOnNext(brIfDivisorNonZero)
 
 	// Temporarily mark them used to allocate a result register while keeping these values.
@@ -2421,7 +2418,7 @@ func (c *arm64Compiler) compileITruncFromF(o *wazeroir.OperationITruncFromF) err
 	// See https://developer.arm.com/documentation/ddi0595/2020-12/AArch64-Registers/FPSR--Floating-point-Status-Register
 	c.compileRegisterAndConstSourceToNoneInstruction(arm64.ACMP, reservedRegisterForTemporary, 1)
 
-	brOK := c.compilelBranchInstruction(arm64.ABNE)
+	brOK := c.compileBranchInstruction(arm64.ABNE)
 
 	// If so, exit the execution with errors depending on whether or not the source value is NaN.
 	{
@@ -2434,7 +2431,7 @@ func (c *arm64Compiler) compileITruncFromF(o *wazeroir.OperationITruncFromF) err
 		c.compileTwoRegistersToNoneInstruction(floatcmp, source.register, source.register)
 		// VS flag is set if at least one of values for FCMP is NaN.
 		// https://developer.arm.com/documentation/dui0801/g/Condition-Codes/Comparison-of-condition-code-meanings-in-integer-and-floating-point-code
-		brIfSourceNaN := c.compilelBranchInstruction(arm64.ABVS)
+		brIfSourceNaN := c.compileBranchInstruction(arm64.ABVS)
 
 		// If the source value is not NaN, the operation was overflow.
 		if err := c.compileExitFromNativeCode(jitCallStatusIntegerOverflow); err != nil {
@@ -2988,7 +2985,7 @@ func (c *arm64Compiler) compileMemoryAccessOffsetSetup(offsetArg uint32, targetS
 
 	// Check if offsetRegister(= base+offsetArg+targetSizeInBytes) > len(memory.Buffer).
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMP, reservedRegisterForTemporary, offsetRegister)
-	boundsOK := c.compilelBranchInstruction(arm64.ABLS)
+	boundsOK := c.compileBranchInstruction(arm64.ABLS)
 
 	// If offsetRegister(= base+offsetArg+targetSizeInBytes) exceeds the memory length,
 	//  we exit the function with jitCallStatusCodeMemoryOutOfBounds.
@@ -3244,7 +3241,7 @@ func (c *arm64Compiler) compileEnsureOnGeneralPurposeRegister(loc *valueLocation
 // if the value is located on a conditional register.
 //
 // This is usually called at the beginning of methods on compiler interface where we possibly
-// compile istructions without saving the conditional register value.
+// compile instructions without saving the conditional register value.
 // The compile* functions without calling this function is saving the conditional
 // value to the stack or register by invoking ensureOnGeneralPurposeRegister for the top.
 func (c *arm64Compiler) maybeCompileMoveTopConditionalToFreeGeneralPurposeRegister() {
@@ -3326,7 +3323,7 @@ func (c *arm64Compiler) allocateRegister(t generalPurposeRegisterType) (reg int1
 }
 
 // compileReleaseAllRegistersToStack adds instructions to store all the values located on
-// either general purpuse or conditional registers onto the memory stack.
+// either general purpose or conditional registers onto the memory stack.
 // See releaseRegisterToStack.
 func (c *arm64Compiler) compileReleaseAllRegistersToStack() error {
 	for i := uint64(0); i < c.locationStack.sp; i++ {
@@ -3358,7 +3355,7 @@ func (c *arm64Compiler) compileReleaseRegisterToStack(loc *valueLocation) (err e
 	return
 }
 
-// compileReservedStackBasePointerRegisterInitialization adds intructions to initialize reservedRegisterForStackBasePointerAddress
+// compileReservedStackBasePointerRegisterInitialization adds instructions to initialize reservedRegisterForStackBasePointerAddress
 // so that it points to the absolute address of the stack base for this function.
 func (c *arm64Compiler) compileReservedStackBasePointerRegisterInitialization() {
 	// First, load the address of the first element in the value stack into reservedRegisterForStackBasePointerAddress temporarily.
@@ -3412,7 +3409,7 @@ func (c *arm64Compiler) compileModuleContextInitialization() error {
 
 	// If the module instance address stays the same, we could skip the entire code below.
 	c.compileTwoRegistersToNoneInstruction(arm64.ACMP, moduleInstanceAddressRegister, tmpX)
-	brIfModuleUnchanged := c.compilelBranchInstruction(arm64.ABEQ)
+	brIfModuleUnchanged := c.compileBranchInstruction(arm64.ABEQ)
 	c.addInstruction(brIfModuleUnchanged)
 
 	// Otherwise, we have to update the following fields:
@@ -3532,7 +3529,7 @@ func (c *arm64Compiler) compileModuleContextInitialization() error {
 	{
 		// "tmpX = [moduleInstanceAddressRegister + moduleInstanceEngineOffset + interfaceDataOffset] (== *moduleEngine)"
 		//
-		// Go's interface is layed out on memory as two quad words as struct {tab, data uintptr}
+		// Go's interface is laid out on memory as two quad words as struct {tab, data uintptr}
 		// where tab points to the interface table, and the latter points to the actual
 		// implementation of interface. This case, we extract "data" pointer as *moduleEngine.
 		// See the following references for detail:
diff --git a/internal/wasm/jit/jit_value_location.go b/internal/wasm/jit/jit_value_location.go
index 6fc4c72a..d72d3e71 100644
--- a/internal/wasm/jit/jit_value_location.go
+++ b/internal/wasm/jit/jit_value_location.go
@@ -97,7 +97,7 @@ func newValueLocationStack() *valueLocationStack {
 // Notably this is only used in the compilation phase, not runtime,
 // and we change the state of this struct at every wazeroir operation we compile.
 // In this way, we can see where the operands of a operation (for example,
-// two variables for wazeroir add operation.) exist and check the neccesity for
+// two variables for wazeroir add operation.) exist and check the necessity for
 // moving the variable to registers to perform actual CPU instruction
 // to achieve wazeroir's add operation.
 type valueLocationStack struct {
diff --git a/internal/wasm/jit/jit_value_location_amd64.go b/internal/wasm/jit/jit_value_location_amd64.go
index 5ecd5cb3..ae8c27ac 100644
--- a/internal/wasm/jit/jit_value_location_amd64.go
+++ b/internal/wasm/jit/jit_value_location_amd64.go
@@ -1,5 +1,3 @@
-//go:build amd64
-
 package jit
 
 import (
@@ -27,7 +25,7 @@ var (
 		x86.REG_X12, x86.REG_X13, x86.REG_X14, x86.REG_X15,
 	}
 	// Note that we never invoke "call" instruction,
-	// so we don't need to care about the calling convension.
+	// so we don't need to care about the calling convention.
 	// TODO: Maybe it is safe just save rbp, rsp somewhere
 	// in Go-allocated variables, and reuse these registers
 	// in JITed functions and write them back before returns.
diff --git a/internal/wasm/jit/jit_value_location_arm64.go b/internal/wasm/jit/jit_value_location_arm64.go
index 867fd920..27eaac36 100644
--- a/internal/wasm/jit/jit_value_location_arm64.go
+++ b/internal/wasm/jit/jit_value_location_arm64.go
@@ -1,14 +1,12 @@
-//go:build arm64
-
 package jit
 
 import "github.com/twitchyliquid64/golang-asm/obj/arm64"
 
 // Reserved registers.
 const (
-	// reservedRegisterForCallEngine holds the pointer to callEngine instance (i.e. *virtulMachine as uintptr)
+	// reservedRegisterForCallEngine holds the pointer to callEngine instance (i.e. *callEngine as uintptr)
 	reservedRegisterForCallEngine = arm64.REG_R0
-	// reservedRegisterForStackBasePointerAddress holds stack base pointer's address (virtulMachine.stackBasePointer) in the current function call.
+	// reservedRegisterForStackBasePointerAddress holds stack base pointer's address (callEngine.stackBasePointer) in the current function call.
 	reservedRegisterForStackBasePointerAddress = arm64.REG_R1
 	// reservedRegisterForMemory holds the pointer to the memory slice's data (i.e. &memory.Buffer[0] as uintptr).
 	reservedRegisterForMemory    = arm64.REG_R2
diff --git a/internal/wasm/jit/mmap.go b/internal/wasm/jit/mmap.go
index 1e822d90..8ea2b321 100644
--- a/internal/wasm/jit/mmap.go
+++ b/internal/wasm/jit/mmap.go
@@ -23,7 +23,7 @@ func munmapCodeSegment(code []byte) error {
 }
 
 // mmapCodeSegmentAMD64 gives all read-write-exec permission to the mmap region
-// to enter the function. Otherwise, segmentation fault exeception is raied.
+// to enter the function. Otherwise, segmentation fault exception is raised.
 func mmapCodeSegmentAMD64(code []byte) ([]byte, error) {
 	mmapFunc, err := syscall.Mmap(
 		-1,
diff --git a/internal/wasm/jit/mmap_windows.go b/internal/wasm/jit/mmap_windows.go
index 82faf939..9bdde14a 100644
--- a/internal/wasm/jit/mmap_windows.go
+++ b/internal/wasm/jit/mmap_windows.go
@@ -8,10 +8,10 @@ import (
 )
 
 var (
-	kenerl32           = syscall.NewLazyDLL("kernel32.dll")
-	procVirtualAlloc   = kenerl32.NewProc("VirtualAlloc")
-	procVirtualProtect = kenerl32.NewProc("VirtualProtect")
-	procVirtualFree    = kenerl32.NewProc("VirtualFree")
+	kernel32           = syscall.NewLazyDLL("kernel32.dll")
+	procVirtualAlloc   = kernel32.NewProc("VirtualAlloc")
+	procVirtualProtect = kernel32.NewProc("VirtualProtect")
+	procVirtualFree    = kernel32.NewProc("VirtualFree")
 )
 
 const (
diff --git a/internal/wasm/memory.go b/internal/wasm/memory.go
index 8af4777b..99d2215d 100644
--- a/internal/wasm/memory.go
+++ b/internal/wasm/memory.go
@@ -147,7 +147,7 @@ func memoryBytesNumToPages(bytesNum uint64) (pages uint32) {
 // Grow extends the memory buffer by "newPages" * memoryPageSize.
 // The logic here is described in https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#grow-mem.
 //
-// Returns -1 if the operation resulted in excedding the maximum memory pages.
+// Returns -1 if the operation resulted in exceeding the maximum memory pages.
 // Otherwise, returns the prior memory size after growing the memory buffer.
 func (m *MemoryInstance) Grow(newPages uint32) (result uint32) {
 	currentPages := memoryBytesNumToPages(uint64(len(m.Buffer)))
diff --git a/internal/wasm/module.go b/internal/wasm/module.go
index 3fe1ccbe..5cdda977 100644
--- a/internal/wasm/module.go
+++ b/internal/wasm/module.go
@@ -164,7 +164,7 @@ const (
 
 // TypeOfFunction returns the internalwasm.SectionIDType index for the given function namespace index or nil.
 // Note: The function index namespace is preceded by imported functions.
-// TODO: Returning nil should be impossible when decode results are validated. Validate decode before backfilling tests.
+// TODO: Returning nil should be impossible when decode results are validated. Validate decode before back-filling tests.
 func (m *Module) TypeOfFunction(funcIdx Index) *FunctionType {
 	typeSectionLength := uint32(len(m.TypeSection))
 	if typeSectionLength == 0 {
@@ -325,19 +325,6 @@ func (m *Module) funcDesc(sectionID SectionID, sectionIndex Index) string {
 	return fmt.Sprintf("%s[%d] export[%s]", sectionIDName, sectionIndex, strings.Join(exportNames, ","))
 }
 
-func (m *Module) validateTable(table *Table, globals []*GlobalType) error {
-	for _, elem := range m.ElementSection {
-		if table == nil {
-			return fmt.Errorf("table index out of range")
-		}
-		err := validateConstExpression(globals, elem.OffsetExpr, ValueTypeI32)
-		if err != nil {
-			return fmt.Errorf("invalid const expression for element: %w", err)
-		}
-	}
-	return nil
-}
-
 func (m *Module) validateMemory(memory *Memory, globals []*GlobalType) error {
 	if len(m.DataSection) > 0 && memory == nil {
 		return fmt.Errorf("unknown memory")
@@ -457,10 +444,7 @@ func (m *Module) buildGlobals(importedGlobals []*GlobalInstance) (globals []*Glo
 		case float64:
 			gv = publicwasm.EncodeF64(v)
 		}
-		globals = append(globals, &GlobalInstance{
-			Type: gs.Type,
-			Val:  gv,
-		})
+		globals = append(globals, &GlobalInstance{Type: gs.Type, Val: gv})
 	}
 	return
 }
@@ -594,9 +578,6 @@ type limitsType struct {
 	Max *uint32
 }
 
-// Table describes the limits of (function) elements in a table.
-type Table = limitsType
-
 // Memory describes the limits of pages (64KB) in a memory.
 type Memory = limitsType
 
@@ -628,19 +609,6 @@ type Export struct {
 	Index Index
 }
 
-// ElementSegment are initialization instructions for a TableInstance
-//
-// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-elem
-type ElementSegment struct {
-	// OffsetExpr returns the table element offset to apply to Init indices.
-	// Note: This can be validated prior to instantiation unless it includes OpcodeGlobalGet (an imported global).
-	OffsetExpr *ConstantExpression
-
-	// Init indices are table elements relative to the result of OffsetExpr. The values are positions in the function
-	// index namespace that initialize the corresponding element.
-	Init []Index
-}
-
 // Code is an entry in the Module.CodeSection containing the locals and body of the function.
 // See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#binary-code
 type Code struct {
diff --git a/internal/wasm/store.go b/internal/wasm/store.go
index 406997aa..8c3ad26d 100644
--- a/internal/wasm/store.go
+++ b/internal/wasm/store.go
@@ -156,19 +156,6 @@ type (
 		Val uint64
 	}
 
-	// TableInstance represents a table instance in a store.
-	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#table-instances%E2%91%A0
-	TableInstance struct {
-		// Table holds the table elements managed by this table instance.
-		Table []uintptr
-
-		// Min is the minimum (function) elements in this table.
-		Min uint32
-
-		// Max if present is the maximum (function) elements in this table, or nil if unbounded.
-		Max *uint32
-	}
-
 	// FunctionTypeID is a uniquely assigned integer for a function type.
 	// This is wazero specific runtime object and specific to a store,
 	// and used at runtime to do type-checks on indirect function calls.
@@ -264,34 +251,6 @@ func (m *ModuleInstance) applyData(data []*DataSegment) {
 	}
 }
 
-func (m *ModuleInstance) validateElements(elements []*ElementSegment) (err error) {
-	for _, elem := range elements {
-		offset := int(executeConstExpression(m.Globals, elem.OffsetExpr).(int32))
-		ceil := offset + len(elem.Init)
-
-		if offset < 0 || ceil > len(m.Table.Table) {
-			return fmt.Errorf("out of bounds table access")
-		}
-		for _, elm := range elem.Init {
-			if elm >= uint32(len(m.Functions)) {
-				return fmt.Errorf("unknown function specified by element")
-			}
-		}
-	}
-	return
-}
-
-func (m *ModuleInstance) applyElements(elements []*ElementSegment) {
-	for _, elem := range elements {
-		offset := int(executeConstExpression(m.Globals, elem.OffsetExpr).(int32))
-		table := m.Table.Table
-		for i, elm := range elem.Init {
-			pos := i + offset
-			table[pos] = m.Engine.FunctionAddress(elm)
-		}
-	}
-}
-
 // GetExport returns an export of the given name and type or errs if not exported or the wrong type.
 func (m *ModuleInstance) getExport(name string, et ExternType) (*ExportInstance, error) {
 	exp, ok := m.Exports[name]
@@ -362,7 +321,7 @@ func (s *Store) Instantiate(module *Module, name string) (*ModuleContext, error)
 		globals, importedTable, table, importedMemory, memory, types, moduleImports)
 
 	// Plus we are ready to compile functions.
-	m.Engine, err = s.engine.Compile(importedFunctions, functions)
+	m.Engine, err = s.engine.NewModuleEngine(importedFunctions, functions)
 	if err != nil {
 		return nil, fmt.Errorf("compilation failed: %w", err)
 	}
@@ -637,7 +596,7 @@ func executeConstExpression(globals []*GlobalInstance, expr *ConstantExpression)
 }
 
 func (s *Store) getTypes(ts []*FunctionType) ([]*TypeInstance, error) {
-	// We take write-lock here as the follwing might end up mutating typeIDs map.
+	// We take write-lock here as the following might end up mutating typeIDs map.
 	s.mux.Lock()
 	defer s.mux.Unlock()
 	ret := make([]*TypeInstance, len(ts))
diff --git a/internal/wasm/table.go b/internal/wasm/table.go
index 96c29774..6b104a2d 100644
--- a/internal/wasm/table.go
+++ b/internal/wasm/table.go
@@ -1,5 +1,36 @@
 package internalwasm
 
+import "fmt"
+
+// Table describes the limits of (function) elements in a table.
+type Table = limitsType
+
+// ElementSegment are initialization instructions for a TableInstance
+//
+// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#syntax-elem
+type ElementSegment struct {
+	// OffsetExpr returns the table element offset to apply to Init indices.
+	// Note: This can be validated prior to instantiation unless it includes OpcodeGlobalGet (an imported global).
+	OffsetExpr *ConstantExpression
+
+	// Init indices are table elements relative to the result of OffsetExpr. The values are positions in the function
+	// index namespace that initialize the corresponding element.
+	Init []Index
+}
+
+// TableInstance represents a table instance in a store.
+// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#table-instances%E2%91%A0
+type TableInstance struct {
+	// Table holds the table elements managed by this table instance.
+	Table []uintptr
+
+	// Min is the minimum (function) elements in this table.
+	Min uint32
+
+	// Max if present is the maximum (function) elements in this table, or nil if unbounded.
+	Max *uint32
+}
+
 func (m *Module) buildTable() *TableInstance {
 	table := m.TableSection
 	if table != nil {
@@ -11,3 +42,44 @@ func (m *Module) buildTable() *TableInstance {
 	}
 	return nil
 }
+
+func (m *Module) validateTable(table *Table, globals []*GlobalType) error {
+	for _, elem := range m.ElementSection {
+		if table == nil {
+			return fmt.Errorf("table index out of range")
+		}
+		err := validateConstExpression(globals, elem.OffsetExpr, ValueTypeI32)
+		if err != nil {
+			return fmt.Errorf("invalid const expression for element: %w", err)
+		}
+	}
+	return nil
+}
+
+func (m *ModuleInstance) validateElements(elements []*ElementSegment) (err error) {
+	for _, elem := range elements {
+		offset := int(executeConstExpression(m.Globals, elem.OffsetExpr).(int32))
+		ceil := offset + len(elem.Init)
+
+		if offset < 0 || ceil > len(m.Table.Table) {
+			return fmt.Errorf("out of bounds table access")
+		}
+		for _, elm := range elem.Init {
+			if elm >= uint32(len(m.Functions)) {
+				return fmt.Errorf("unknown function specified by element")
+			}
+		}
+	}
+	return
+}
+
+func (m *ModuleInstance) applyElements(elements []*ElementSegment) {
+	for _, elem := range elements {
+		offset := int(executeConstExpression(m.Globals, elem.OffsetExpr).(int32))
+		table := m.Table.Table
+		for i, elm := range elem.Init {
+			pos := i + offset
+			table[pos] = m.Engine.FunctionAddress(elm)
+		}
+	}
+}
diff --git a/internal/wazeroir/compiler.go b/internal/wazeroir/compiler.go
index df9479ef..b82d8f65 100644
--- a/internal/wazeroir/compiler.go
+++ b/internal/wazeroir/compiler.go
@@ -137,7 +137,7 @@ type CompilationResult struct {
 	// Operations holds wazeroir operations compiled from Wasm instructions in a Wasm function.
 	Operations []Operation
 	// LabelCallers maps Label.String() to the number of callers to that label.
-	// Here "callers" means that the callsites which jumps to the label with br, br_if or br_table
+	// Here "callers" means that the call-sites which jumps to the label with br, br_if or br_table
 	// instructions.
 	//
 	// Note: zero possible and allowed in wasm. Ex.
@@ -360,7 +360,7 @@ operatorSwitch:
 		dropOp := &OperationDrop{Range: c.getFrameDropRange(frame)}
 		c.stack = c.stack[:frame.originalStackLen]
 
-		// Prep labels for else and the continueation of this if block.
+		// Prep labels for else and the continuation of this if block.
 		elseLabel := &Label{FrameID: frame.frameID, Kind: LabelKindElse, OriginalStackLen: frame.originalStackLen}
 		continuationLabel := &Label{FrameID: frame.frameID, Kind: LabelKindContinuation}
 		c.result.LabelCallers[continuationLabel.String()]++
@@ -1436,7 +1436,7 @@ func (c *compiler) applyToStack(opcode wasm.Opcode) (*uint32, error) {
 		return nil, err
 	}
 
-	// Manipulate the stack according to the signtature.
+	// Manipulate the stack according to the signature.
 	// Note that the following algorithm assumes that
 	// the unknown type is unique in the signature,
 	// and is determined by the actual type on the stack.
@@ -1483,14 +1483,14 @@ func (c *compiler) stackPush(t UnsignedType) {
 	c.stack = append(c.stack, t)
 }
 
-// Emit the operatiosn into the result.
+// emit adds the operations into the result.
 func (c *compiler) emit(ops ...Operation) {
 	if !c.unreachableState.on {
 		for _, op := range ops {
 			switch o := op.(type) {
 			case *OperationDrop:
 				// If the drop range is nil,
-				// we could remove such operatinos.
+				// we could remove such operations.
 				// That happens when drop operation is unnecessary.
 				// i.e. when there's no need to adjust stack before jmp.
 				if o.Range == nil {
diff --git a/internal/wazeroir/operations.go b/internal/wazeroir/operations.go
index 7d4fb1e1..4bf45901 100644
--- a/internal/wazeroir/operations.go
+++ b/internal/wazeroir/operations.go
@@ -590,7 +590,7 @@ func (o *OperationMemorySize) Kind() OperationKind {
 	return OperationKindMemorySize
 }
 
-type OperationMemoryGrow struct{ Aligment uint64 }
+type OperationMemoryGrow struct{ Alignment uint64 }
 
 func (o *OperationMemoryGrow) Kind() OperationKind {
 	return OperationKindMemoryGrow
diff --git a/internal/wazeroir/signature.go b/internal/wazeroir/signature.go
index d23abc3a..d46e8cd3 100644
--- a/internal/wazeroir/signature.go
+++ b/internal/wazeroir/signature.go
@@ -136,7 +136,7 @@ var (
 		in:  []UnsignedType{UnsignedTypeF64, UnsignedTypeF64},
 		out: []UnsignedType{UnsignedTypeF64},
 	}
-	signature_UnknownUnkownI32_Unknown = &signature{
+	signature_UnknownUnknownI32_Unknown = &signature{
 		in:  []UnsignedType{UnsignedTypeUnknown, UnsignedTypeUnknown, UnsignedTypeI32},
 		out: []UnsignedType{UnsignedTypeUnknown},
 	}
@@ -168,7 +168,7 @@ func wasmOpcodeSignature(f *wasm.FunctionInstance, op wasm.Opcode, index uint32)
 	case wasm.OpcodeDrop:
 		return signature_Unknown_None, nil
 	case wasm.OpcodeSelect:
-		return signature_UnknownUnkownI32_Unknown, nil
+		return signature_UnknownUnknownI32_Unknown, nil
 	case wasm.OpcodeLocalGet:
 		inputLen := uint32(len(f.Type.Params))
 		if l := uint32(len(f.LocalTypes)) + inputLen; index >= l {
diff --git a/wasm.go b/wasm.go
index 20e0854c..efe8b4a5 100644
--- a/wasm.go
+++ b/wasm.go
@@ -35,6 +35,10 @@ type Runtime interface {
 	// CompileModule decodes the WebAssembly 1.0 (20191205) text or binary source or errs if invalid.
 	// Any pre-compilation done after decoding the source is dependent on the RuntimeConfig.
 	//
+	// There are two main reasons to use CompileModule instead of InstantiateModuleFromSource:
+	//  * Improve performance when the same module is instantiated multiple times under different names
+	//  * Reduce the amount of errors that can occur during InstantiateModule.
+	//
 	// Note: The resulting module name defaults to what was decoded from the custom name section.
 	// See https://www.w3.org/TR/2019/REC-wasm-core-1-20191205/#name-section%E2%91%A0
 	CompileModule(source []byte) (*Module, error)
@@ -56,7 +60,12 @@ type Runtime interface {
 	//	decoded, _ := r.CompileModule(source)
 	//	module, _ := r.InstantiateModule(decoded)
 	//
-	// Note: The last value of RuntimeConfig.WithContext is used for any WebAssembly 1.0 (20191205) Start ExportedFunction.
+	// While a Module is pre-validated, there are a few situations which can cause an error:
+	//  * The Module name is already in use.
+	//  * The Module has a table element initializer that uses an imported global offset that puts it out of range.
+	//  * The Module has a start function, and it failed to execute.
+	//
+	// Note: The last value of RuntimeConfig.WithContext is used for any start function.
 	InstantiateModule(module *Module) (wasm.Module, error)
 
 	// TODO: RemoveModule


Test patch:
diff --git a/internal/wasi/wasi_test.go b/internal/wasi/wasi_test.go
index 8e129c88..dd56826e 100644
--- a/internal/wasi/wasi_test.go
+++ b/internal/wasi/wasi_test.go
@@ -938,7 +938,7 @@ func TestSnapshotPreview1_FdRead_Errors(t *testing.T) {
 			iovs: 1, iovsCount: 1,
 			memory: []byte{
 				'?',          // `iovs` is after this
-				0, 0, 0x1, 0, // = iovs[0].offset on the secod page
+				0, 0, 0x1, 0, // = iovs[0].offset on the second page
 				1, 0, 0, 0, // = iovs[0].length
 			},
 			expectedErrno: wasi.ErrnoFault,
@@ -950,7 +950,7 @@ func TestSnapshotPreview1_FdRead_Errors(t *testing.T) {
 			memory: []byte{
 				'?',        // `iovs` is after this
 				9, 0, 0, 0, // = iovs[0].offset
-				0, 0, 0x1, 0, // = iovs[0].length on the secod page
+				0, 0, 0x1, 0, // = iovs[0].length on the second page
 				'?',
 			},
 			expectedErrno: wasi.ErrnoFault,
@@ -1106,7 +1106,7 @@ func TestSnapshotPreview1_FdSeek(t *testing.T) {
 					require.True(t, ok)
 					require.Equal(t, tc.expectedMemory, actual)
 
-					require.Equal(t, tc.expectedOffset, file.offset) // test that the offset of file is acutally updated.
+					require.Equal(t, tc.expectedOffset, file.offset) // test that the offset of file is actually updated.
 				})
 			}
 		})
@@ -1431,7 +1431,7 @@ func TestSnapshotPreview1_PathOpen(t *testing.T) {
 
 	var api *wasiAPI
 	mod, fn := instantiateModule(t, FunctionPathOpen, ImportPathOpen, moduleName, func(a *wasiAPI) {
-		// randSouce is used to determine the new fd. Fix it to the expectedFD for testing.
+		// randSource is used to determine the new fd. Fix it to the expectedFD for testing.
 		a.randSource = func(b []byte) error {
 			binary.LittleEndian.PutUint32(b, expectedFD)
 			return nil
diff --git a/internal/wasm/interpreter/interpreter_test.go b/internal/wasm/interpreter/interpreter_test.go
index f092d695..320f6469 100644
--- a/internal/wasm/interpreter/interpreter_test.go
+++ b/internal/wasm/interpreter/interpreter_test.go
@@ -102,24 +102,24 @@ func TestEngine_Call_HostFn(t *testing.T) {
 		Module: module,
 	}
 
-	modEngine, err := e.Compile(nil, []*wasm.FunctionInstance{f})
+	me, err := e.NewModuleEngine(nil, []*wasm.FunctionInstance{f})
 	require.NoError(t, err)
 
 	t.Run("defaults to module memory when call stack empty", func(t *testing.T) {
 		// When calling a host func directly, there may be no stack. This ensures the module's memory is used.
-		results, err := modEngine.Call(modCtx, f, 3)
+		results, err := me.Call(modCtx, f, 3)
 		require.NoError(t, err)
 		require.Equal(t, uint64(3), results[0])
 		require.Same(t, memory, ctxMemory)
 	})
 
 	t.Run("errs when not enough parameters", func(t *testing.T) {
-		_, err := modEngine.Call(modCtx, f)
+		_, err := me.Call(modCtx, f)
 		require.EqualError(t, err, "expected 1 params, but passed 0")
 	})
 
 	t.Run("errs when too many parameters", func(t *testing.T) {
-		_, err := modEngine.Call(modCtx, f, 1, 2)
+		_, err := me.Call(modCtx, f, 1, 2)
 		require.EqualError(t, err, "expected 1 params, but passed 2")
 	})
 }
@@ -239,7 +239,10 @@ func TestCallEngine_callNativeFunc_signExtend(t *testing.T) {
 func TestEngineCompile_Errors(t *testing.T) {
 	t.Run("invalid import", func(t *testing.T) {
 		e := NewEngine().(*engine)
-		_, err := e.Compile([]*wasm.FunctionInstance{{Module: &wasm.ModuleInstance{Name: "uncompiled"}, Name: "fn"}}, nil)
+		_, err := e.NewModuleEngine(
+			[]*wasm.FunctionInstance{{Module: &wasm.ModuleInstance{Name: "uncompiled"}, Name: "fn"}},
+			nil, // moduleFunctions
+		)
 		require.EqualError(t, err, "import[0] func[uncompiled.fn]: uncompiled")
 	})
 
@@ -252,7 +255,9 @@ func TestEngineCompile_Errors(t *testing.T) {
 			{Name: "3", Type: &wasm.FunctionType{}, Body: []byte{wasm.OpcodeEnd}, Module: &wasm.ModuleInstance{}},
 			{Name: "4", Type: &wasm.FunctionType{}, Body: []byte{wasm.OpcodeEnd}, Module: &wasm.ModuleInstance{}},
 		}
-		_, err := e.Compile(nil, importedFunctions)
+
+		// initialize the module-engine containing imported functions
+		_, err := e.NewModuleEngine(nil, importedFunctions)
 		require.NoError(t, err)
 
 		require.Len(t, e.compiledFunctions, len(importedFunctions))
@@ -265,10 +270,10 @@ func TestEngineCompile_Errors(t *testing.T) {
 			}, Module: &wasm.ModuleInstance{}},
 		}
 
-		_, err = e.Compile(importedFunctions, moduleFunctions)
+		_, err = e.NewModuleEngine(importedFunctions, moduleFunctions)
 		require.EqualError(t, err, "function[2/2] failed to lower to wazeroir: handling instruction: apply stack failed for call: reading immediates: EOF")
 
-		// On the compilation failrue, all the compiled functions including suceeded ones must be released.
+		// On the compilation failure, all the compiled functions including succeeded ones must be released.
 		require.Len(t, e.compiledFunctions, len(importedFunctions))
 		for _, f := range moduleFunctions {
 			require.NotContains(t, e.compiledFunctions, f)
@@ -287,7 +292,7 @@ func TestRelease(t *testing.T) {
 		importedFunctions, moduleFunctions []*wasm.FunctionInstance
 	}{
 		{
-			name:            "no imports",
+			name:            "only module-defined",
 			moduleFunctions: []*wasm.FunctionInstance{newFunctionInstance(0), newFunctionInstance(1)},
 		},
 		{
@@ -295,7 +300,7 @@ func TestRelease(t *testing.T) {
 			importedFunctions: []*wasm.FunctionInstance{newFunctionInstance(0), newFunctionInstance(1)},
 		},
 		{
-			name:              "mix",
+			name:              "imports and module-defined",
 			importedFunctions: []*wasm.FunctionInstance{newFunctionInstance(0), newFunctionInstance(1)},
 			moduleFunctions:   []*wasm.FunctionInstance{newFunctionInstance(100), newFunctionInstance(200), newFunctionInstance(300)},
 		},
@@ -304,14 +309,15 @@ func TestRelease(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			e := NewEngine().(*engine)
 			if len(tc.importedFunctions) > 0 {
-				modEngine, err := e.Compile(nil, tc.importedFunctions)
+				// initialize the module-engine containing imported functions
+				me, err := e.NewModuleEngine(nil, tc.importedFunctions)
 				require.NoError(t, err)
-				require.Len(t, modEngine.(*moduleEngine).compiledFunctions, len(tc.importedFunctions))
+				require.Len(t, me.(*moduleEngine).compiledFunctions, len(tc.importedFunctions))
 			}
 
-			modEngine, err := e.Compile(tc.importedFunctions, tc.moduleFunctions)
+			me, err := e.NewModuleEngine(tc.importedFunctions, tc.moduleFunctions)
 			require.NoError(t, err)
-			require.Len(t, modEngine.(*moduleEngine).compiledFunctions, len(tc.importedFunctions)+len(tc.moduleFunctions))
+			require.Len(t, me.(*moduleEngine).compiledFunctions, len(tc.importedFunctions)+len(tc.moduleFunctions))
 
 			require.Len(t, e.compiledFunctions, len(tc.importedFunctions)+len(tc.moduleFunctions))
 			for _, f := range tc.importedFunctions {
@@ -321,7 +327,7 @@ func TestRelease(t *testing.T) {
 				require.Contains(t, e.compiledFunctions, f)
 			}
 
-			err = modEngine.Release()
+			err = me.Release()
 			require.NoError(t, err)
 
 			require.Len(t, e.compiledFunctions, len(tc.importedFunctions))
diff --git a/internal/wasm/jit/engine_test.go b/internal/wasm/jit/engine_test.go
index e18b3997..c63dd278 100644
--- a/internal/wasm/jit/engine_test.go
+++ b/internal/wasm/jit/engine_test.go
@@ -48,7 +48,7 @@ func TestVerifyOffsetValue(t *testing.T) {
 	// Size and offsets for callFrame.
 	var frame callFrame
 	require.Equal(t, int(unsafe.Sizeof(frame)), callFrameDataSize)
-	// Sizeof callframe must be a power of 2 as we do SHL on the index by "callFrameDataSizeMostSignificantSetBit" to obtain the offset address.
+	// Sizeof call-frame must be a power of 2 as we do SHL on the index by "callFrameDataSizeMostSignificantSetBit" to obtain the offset address.
 	require.True(t, callFrameDataSize&(callFrameDataSize-1) == 0)
 	require.Equal(t, math.Ilogb(float64(callFrameDataSize)), callFrameDataSizeMostSignificantSetBit)
 	require.Equal(t, int(unsafe.Offsetof(frame.returnAddress)), callFrameReturnAddressOffset)
@@ -157,7 +157,7 @@ func TestEngine_Call_HostFn(t *testing.T) {
 		Module: module,
 	}
 
-	modEngine, err := e.Compile(nil, []*wasm.FunctionInstance{f})
+	modEngine, err := e.NewModuleEngine(nil, []*wasm.FunctionInstance{f})
 	require.NoError(t, err)
 
 	t.Run("defaults to module memory when call stack empty", func(t *testing.T) {
@@ -188,7 +188,7 @@ func requireSupportedOSArch(t *testing.T) {
 func TestEngineCompile_Errors(t *testing.T) {
 	t.Run("invalid import", func(t *testing.T) {
 		e := newEngine()
-		_, err := e.Compile([]*wasm.FunctionInstance{{Module: &wasm.ModuleInstance{Name: "uncompiled"}, Name: "fn"}}, nil)
+		_, err := e.NewModuleEngine([]*wasm.FunctionInstance{{Module: &wasm.ModuleInstance{Name: "uncompiled"}, Name: "fn"}}, nil)
 		require.EqualError(t, err, "import[0] func[uncompiled.fn]: uncompiled")
 	})
 
@@ -201,7 +201,7 @@ func TestEngineCompile_Errors(t *testing.T) {
 			{Name: "3", Type: &wasm.FunctionType{}, Body: []byte{wasm.OpcodeEnd}, Module: &wasm.ModuleInstance{}},
 			{Name: "4", Type: &wasm.FunctionType{}, Body: []byte{wasm.OpcodeEnd}, Module: &wasm.ModuleInstance{}},
 		}
-		_, err := e.Compile(nil, importedFunctions)
+		_, err := e.NewModuleEngine(nil, importedFunctions)
 		require.NoError(t, err)
 
 		require.Len(t, e.compiledFunctions, len(importedFunctions))
@@ -214,10 +214,10 @@ func TestEngineCompile_Errors(t *testing.T) {
 			}, Module: &wasm.ModuleInstance{}},
 		}
 
-		_, err = e.Compile(importedFunctions, moduleFunctions)
+		_, err = e.NewModuleEngine(importedFunctions, moduleFunctions)
 		require.EqualError(t, err, "function[2/2] failed to lower to wazeroir: handling instruction: apply stack failed for call: reading immediates: EOF")
 
-		// On the compilation failrue, all the compiled functions including suceeded ones must be released.
+		// On the compilation failure, all the compiled functions including succeeded ones must be released.
 		require.Len(t, e.compiledFunctions, len(importedFunctions))
 		for _, f := range moduleFunctions {
 			require.NotContains(t, e.compiledFunctions, f)
@@ -253,12 +253,12 @@ func TestRelease(t *testing.T) {
 		t.Run(tc.name, func(t *testing.T) {
 			e := newEngine()
 			if len(tc.importedFunctions) > 0 {
-				modEngine, err := e.Compile(nil, tc.importedFunctions)
+				modEngine, err := e.NewModuleEngine(nil, tc.importedFunctions)
 				require.NoError(t, err)
 				require.Len(t, modEngine.(*moduleEngine).compiledFunctions, len(tc.importedFunctions))
 			}
 
-			modEngine, err := e.Compile(tc.importedFunctions, tc.moduleFunctions)
+			modEngine, err := e.NewModuleEngine(tc.importedFunctions, tc.moduleFunctions)
 			require.NoError(t, err)
 			require.Len(t, modEngine.(*moduleEngine).compiledFunctions, len(tc.importedFunctions)+len(tc.moduleFunctions))
 
@@ -284,7 +284,7 @@ func TestRelease(t *testing.T) {
 	}
 }
 
-// Ensures that value stack and callframe stack are allocated on heap which
+// Ensures that value stack and call-frame stack are allocated on heap which
 // allows us to safely access to their data region from native code.
 // See comments on initialValueStackSize and initialCallFrameStackSize.
 func TestSliceAllocatedOnHeap(t *testing.T) {
@@ -346,7 +346,7 @@ func TestSliceAllocatedOnHeap(t *testing.T) {
 					wasm.OpcodeCall, 3, // Call the wasm function below.
 					// At this point, call stack's memory looks like [call_stack_corruption, index3]
 					// With this function call it should end up [call_stack_corruption, host func]
-					// but if the callframe stack is allocated on goroutine stack, we exit the native code
+					// but if the call-frame stack is allocated on goroutine stack, we exit the native code
 					// with  [call_stack_corruption, index3] (old call frame stack) with HostCall status code,
 					// and end up trying to call index3 as a host function which results in nil pointer exception.
 					wasm.OpcodeCall, 0,
diff --git a/internal/wasm/jit/jit_amd64_test.go b/internal/wasm/jit/jit_amd64_test.go
index b138d679..5061916c 100644
--- a/internal/wasm/jit/jit_amd64_test.go
+++ b/internal/wasm/jit/jit_amd64_test.go
@@ -1,5 +1,3 @@
-//go:build amd64
-
 package jit
 
 import (
@@ -144,7 +142,7 @@ func TestAmd64Compiler_returnFunction(t *testing.T) {
 		code, _, _, err := compiler.compile()
 		require.NoError(t, err)
 
-		// See the previous call frame stack poitner to verify the correctness of exit decision.
+		// See the previous call frame stack pointer to verify the correctness of exit decision.
 		env.setCallFrameStackPointerLen(1)
 
 		// Run codes
@@ -164,7 +162,7 @@ func TestAmd64Compiler_returnFunction(t *testing.T) {
 		stackPointerToExpectedValue := map[uint64]uint32{}
 		for funcindex := wasm.Index(0); funcindex < callFrameNums; funcindex++ {
 			// We have to do compilation in a separate subtest since each compilation takes
-			// the mutext lock and must release on the cleanup of each subtest.
+			// the mutex lock and must release on the cleanup of each subtest.
 			// TODO: delete after https://github.com/tetratelabs/wazero/issues/233
 			t.Run(fmt.Sprintf("compiling existing callframe %d", funcindex), func(t *testing.T) {
 
@@ -220,7 +218,6 @@ func TestAmd64Compiler_returnFunction(t *testing.T) {
 }
 
 func TestAmd64Compiler_initializeModuleContext(t *testing.T) {
-	modEngine := &moduleEngine{compiledFunctions: make([]*compiledFunction, 10)}
 	for _, tc := range []struct {
 		name           string
 		moduleInstance *wasm.ModuleInstance
@@ -228,83 +225,63 @@ func TestAmd64Compiler_initializeModuleContext(t *testing.T) {
 		{
 			name: "no nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Table:   &wasm.TableInstance{Table: make([]uintptr, 20)},
 				Globals: []*wasm.GlobalInstance{{Val: 100}},
-			},
-		},
-		{
-			name: "memory nil",
-			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
+				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Table:   &wasm.TableInstance{Table: make([]uintptr, 20)},
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
 			},
 		},
 		{
-			name: "memory zero length",
+			name: "globals nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Table:   &wasm.TableInstance{Table: make([]uintptr, 20)},
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 0)},
+				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				Table:  &wasm.TableInstance{Table: make([]uintptr, 20)},
 			},
 		},
 		{
-			name: "table length zero",
+			name: "memory nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Table:   &wasm.TableInstance{Table: nil},
 				Globals: []*wasm.GlobalInstance{{Val: 100}},
+				Table:   &wasm.TableInstance{Table: make([]uintptr, 20)},
 			},
 		},
 		{
-			name: "table length zero part2",
+			name: "table nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Table:   &wasm.TableInstance{Table: make([]uintptr, 0)},
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
+				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				Table:  &wasm.TableInstance{Table: nil},
 			},
 		},
 		{
-			name: "table nil",
+			name: "table empty",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Table:   &wasm.TableInstance{},
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
+				Table: &wasm.TableInstance{Table: make([]uintptr, 0)},
 			},
 		},
 		{
-			name: "table nil part2",
+			name: "memory zero length",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
+				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 0)},
 			},
 		},
 		{
-			name: "globals nil",
-			moduleInstance: &wasm.ModuleInstance{
-				Engine: modEngine,
-				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Table:  &wasm.TableInstance{Table: make([]uintptr, 20)},
-			},
+			name:           "all nil except mod engine",
+			moduleInstance: &wasm.ModuleInstance{},
 		},
 	} {
 		tc := tc
 		t.Run(tc.name, func(t *testing.T) {
 			env := newJITEnvironment()
 			ce := env.callEngine()
+
 			compiler := env.requireNewCompiler(t)
-			compiler.initializeReservedStackBasePointer()
+			me := &moduleEngine{compiledFunctions: make([]*compiledFunction, 10)}
+			tc.moduleInstance.Engine = me
 			compiler.f.Module = tc.moduleInstance
 
+			compiler.initializeReservedStackBasePointer()
+
 			require.Empty(t, compiler.locationStack.usedRegisters)
-			err := compiler.initializeModuleContext()
+			err := compiler.compileModuleContextInitialization()
 			require.NoError(t, err)
 
 			require.Empty(t, compiler.locationStack.usedRegisters)
@@ -338,7 +315,7 @@ func TestAmd64Compiler_initializeModuleContext(t *testing.T) {
 				require.Equal(t, tableHeader.Data, ce.moduleContext.tableElement0Address)
 			}
 
-			require.Equal(t, uintptr(unsafe.Pointer(&modEngine.compiledFunctions[0])), ce.moduleContext.compiledFunctionsElement0Address)
+			require.Equal(t, uintptr(unsafe.Pointer(&me.compiledFunctions[0])), ce.moduleContext.compiledFunctionsElement0Address)
 		})
 	}
 }
@@ -1520,7 +1497,7 @@ func TestAmd64Compiler_compileLe_or_Lt(t *testing.T) {
 						}
 						require.NoError(t, err)
 
-						// At this point, all the registesr must be consumed by cmp
+						// At this point, all the registers must be consumed by cmp
 						// so they should be marked as unused.
 						require.NotContains(t, compiler.locationStack.usedRegisters, x1.register)
 						require.NotContains(t, compiler.locationStack.usedRegisters, x2.register)
@@ -1600,7 +1577,7 @@ func TestAmd64Compiler_compileLe_or_Lt(t *testing.T) {
 						}
 						require.NoError(t, err)
 
-						// At this point, all the registesr must be consumed by cmp
+						// At this point, all the registers must be consumed by cmp
 						// so they should be marked as unused.
 						require.NotContains(t, compiler.locationStack.usedRegisters, x1.register)
 						require.NotContains(t, compiler.locationStack.usedRegisters, x2.register)
@@ -1849,7 +1826,7 @@ func TestAmd64Compiler_compileGe_or_Gt(t *testing.T) {
 						}
 						require.NoError(t, err)
 
-						// At this point, all the registesr must be consumed by cmp
+						// At this point, all the registers must be consumed by cmp
 						// so they should be marked as unused.
 						require.NotContains(t, compiler.locationStack.usedRegisters, x1.register)
 						require.NotContains(t, compiler.locationStack.usedRegisters, x2.register)
@@ -1931,7 +1908,7 @@ func TestAmd64Compiler_compileGe_or_Gt(t *testing.T) {
 						}
 						require.NoError(t, err)
 
-						// At this point, all the registesr must be consumed by cmp
+						// At this point, all the registers must be consumed by cmp
 						// so they should be marked as unused.
 						require.NotContains(t, compiler.locationStack.usedRegisters, x1.register)
 						require.NotContains(t, compiler.locationStack.usedRegisters, x2.register)
@@ -2327,7 +2304,7 @@ func TestAmd64Compiler_compileMul(t *testing.T) {
 				x2Reg: x86.REG_AX,
 			},
 			{
-				name:  "x1:staack,x2:ax",
+				name:  "x1:stack,x2:ax",
 				x1Reg: -1,
 				x2Reg: x86.REG_AX,
 			},
@@ -2636,7 +2613,7 @@ func TestAmd64Compiler_compileMul(t *testing.T) {
 	})
 }
 
-func TestAmd64Compiler_compilClz(t *testing.T) {
+func TestAmd64Compiler_compileClz(t *testing.T) {
 	t.Run("32bit", func(t *testing.T) {
 		for _, tc := range []struct{ input, expectedLeadingZeros uint32 }{
 			{input: 0xff_ff_ff_ff, expectedLeadingZeros: 0},
@@ -2734,7 +2711,7 @@ func TestAmd64Compiler_compilClz(t *testing.T) {
 	})
 }
 
-func TestAmd64Compiler_compilCtz(t *testing.T) {
+func TestAmd64Compiler_compileCtz(t *testing.T) {
 	t.Run("32bit", func(t *testing.T) {
 		for _, tc := range []struct{ input, expectedTrailingZeros uint32 }{
 			{input: 0xff_ff_ff_ff, expectedTrailingZeros: 0},
@@ -2831,7 +2808,7 @@ func TestAmd64Compiler_compilCtz(t *testing.T) {
 		}
 	})
 }
-func TestAmd64Compiler_compilPopcnt(t *testing.T) {
+func TestAmd64Compiler_compilePopcnt(t *testing.T) {
 	t.Run("32bit", func(t *testing.T) {
 		for _, tc := range []struct{ input, expectedSetBits uint32 }{
 			{input: 0xff_ff_ff_ff, expectedSetBits: 32},
@@ -2974,7 +2951,7 @@ func TestAmd64Compiler_compile_and_or_xor_shl_shr_rotl_rotr(t *testing.T) {
 					x2Reg: x86.REG_CX,
 				},
 				{
-					name:  "x1:staack,x2:cx",
+					name:  "x1:stack,x2:cx",
 					x1Reg: nilRegister,
 					x2Reg: x86.REG_CX,
 				},
@@ -3197,7 +3174,7 @@ func TestAmd64Compiler_compileDiv(t *testing.T) {
 						x2Reg: x86.REG_AX,
 					},
 					{
-						name:  "x1:staack,x2:ax",
+						name:  "x1:stack,x2:ax",
 						x1Reg: nilRegister,
 						x2Reg: x86.REG_AX,
 					},
@@ -3354,7 +3331,7 @@ func TestAmd64Compiler_compileDiv(t *testing.T) {
 						x2Reg: x86.REG_AX,
 					},
 					{
-						name:  "x1:staack,x2:ax",
+						name:  "x1:stack,x2:ax",
 						x1Reg: nilRegister,
 						x2Reg: x86.REG_AX,
 					},
@@ -3439,7 +3416,7 @@ func TestAmd64Compiler_compileDiv(t *testing.T) {
 								// At this point, the previous value on the DX register is saved to the stack.
 								require.True(t, prevOnDX.onStack())
 
-								// We add the value previously on the DX with the quotiont of the division result
+								// We add the value previously on the DX with the quotient of the division result
 								// in order to ensure that not saving existing DX value would cause
 								// the failure in a subsequent instruction.
 								err = compiler.compileAdd(&wazeroir.OperationAdd{Type: wazeroir.UnsignedTypeI64})
@@ -3657,7 +3634,7 @@ func TestAmd64Compiler_compileRem(t *testing.T) {
 						x2Reg: x86.REG_AX,
 					},
 					{
-						name:  "x1:staack,x2:ax",
+						name:  "x1:stack,x2:ax",
 						x1Reg: nilRegister,
 						x2Reg: x86.REG_AX,
 					},
@@ -3812,7 +3789,7 @@ func TestAmd64Compiler_compileRem(t *testing.T) {
 						x2Reg: x86.REG_AX,
 					},
 					{
-						name:  "x1:staack,x2:ax",
+						name:  "x1:stack,x2:ax",
 						x1Reg: nilRegister,
 						x2Reg: x86.REG_AX,
 					},
@@ -3899,7 +3876,7 @@ func TestAmd64Compiler_compileRem(t *testing.T) {
 								// At this point, the previous value on the DX register is saved to the stack.
 								require.True(t, prevOnDX.onStack())
 
-								// We add the value previously on the DX with the quotiont of the division result
+								// We add the value previously on the DX with the quotient of the division result
 								// in order to ensure that not saving existing DX value would cause
 								// the failure in a subsequent instruction.
 								err = compiler.compileAdd(&wazeroir.OperationAdd{Type: wazeroir.UnsignedTypeI64})
@@ -5670,15 +5647,15 @@ func TestAmd64Compiler_generate(t *testing.T) {
 		}
 		verify := func(t *testing.T, compiler *amd64Compiler, expectedStackPointerCeil uint64) {
 			var called bool
-			compiler.onStackPointerCeilDeterminedCallBack = func(acutalStackPointerCeilInCallBack uint64) {
+			compiler.onStackPointerCeilDeterminedCallBack = func(actualStackPointerCeilInCallBack uint64) {
 				called = true
-				require.Equal(t, expectedStackPointerCeil, acutalStackPointerCeilInCallBack)
+				require.Equal(t, expectedStackPointerCeil, actualStackPointerCeilInCallBack)
 			}
 
-			_, _, acutalStackPointerCeil, err := compiler.compile()
+			_, _, actualStackPointerCeil, err := compiler.compile()
 			require.NoError(t, err)
 			require.True(t, called)
-			require.Equal(t, expectedStackPointerCeil, acutalStackPointerCeil)
+			require.Equal(t, expectedStackPointerCeil, actualStackPointerCeil)
 		}
 		t.Run("current one win", func(t *testing.T) {
 			compiler := getCompiler(t)
@@ -6059,7 +6036,7 @@ func TestAmd64Compiler_compileCall(t *testing.T) {
 				expectedValue += addTargetValue
 
 				// We have to do compilation in a separate subtest since each compilation takes
-				// the mutext lock and must release on the cleanup of each subtest.
+				// the mutex lock and must release on the cleanup of each subtest.
 				// TODO: delete after https://github.com/tetratelabs/wazero/issues/233
 				t.Run(fmt.Sprintf("compiling call target %d", i), func(t *testing.T) {
 					compiler := env.requireNewCompiler(t)
@@ -6149,14 +6126,14 @@ func TestAmd64Compiler_compileCallIndirect(t *testing.T) {
 			Module: &wasm.ModuleInstance{Types: []*wasm.TypeInstance{{Type: &wasm.FunctionType{}}}},
 		}
 
-		// Place the offfset value.
+		// Place the offset value.
 		err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: 10})
 		require.NoError(t, err)
 
 		err = compiler.compileCallIndirect(targetOperation)
 		require.NoError(t, err)
 
-		// We expect to exit from the code in callIndirect so the subsequet code must be unreachable.
+		// We expect to exit from the code in callIndirect so the subsequent code must be unreachable.
 		compiler.exit(jitCallStatusCodeUnreachable)
 
 		// Generate the code under test and run.
@@ -6191,7 +6168,7 @@ func TestAmd64Compiler_compileCallIndirect(t *testing.T) {
 		err = compiler.compileCallIndirect(targetOperation)
 		require.NoError(t, err)
 
-		// We expect to exit from the code in callIndirect so the subsequet code must be unreachable.
+		// We expect to exit from the code in callIndirect so the subsequent code must be unreachable.
 		compiler.exit(jitCallStatusCodeUnreachable)
 
 		// Generate the code under test and run.
@@ -6219,14 +6196,14 @@ func TestAmd64Compiler_compileCallIndirect(t *testing.T) {
 		cf := &compiledFunction{source: &wasm.FunctionInstance{TypeID: 50}}
 		table[0] = uintptr(unsafe.Pointer(cf))
 
-		// Place the offfset value.
+		// Place the offset value.
 		err = compiler.compileConstI32(targetOffset)
 		require.NoError(t, err)
 
 		// Now emit the code.
 		require.NoError(t, compiler.compileCallIndirect(targetOperation))
 
-		// We expect to exit from the code in callIndirect so the subsequet code must be unreachable.
+		// We expect to exit from the code in callIndirect so the subsequent code must be unreachable.
 		compiler.exit(jitCallStatusCodeUnreachable)
 
 		// Generate the code under test and run.
@@ -6262,7 +6239,7 @@ func TestAmd64Compiler_compileCallIndirect(t *testing.T) {
 					expectedReturnValue := uint32(i * 1000)
 
 					// We have to do compilation in a separate subtest since each compilation takes
-					// the mutext lock and must release on the cleanup of each subtest.
+					// the mutex lock and must release on the cleanup of each subtest.
 					// TODO: delete after https://github.com/tetratelabs/wazero/issues/233
 					t.Run(fmt.Sprintf("compiling call target for %d", i), func(t *testing.T) {
 
@@ -6302,7 +6279,7 @@ func TestAmd64Compiler_compileCallIndirect(t *testing.T) {
 
 						compiler.f = &wasm.FunctionInstance{Module: moduleInstance, Kind: wasm.FunctionKindWasm}
 
-						// Place the offfset value. Here we try calling a function of functionaddr == table[i].FunctionIndex.
+						// Place the offset value. Here we try calling a function of functionaddr == table[i].FunctionIndex.
 						err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: uint32(i)})
 						require.NoError(t, err)
 
diff --git a/internal/wasm/jit/jit_arm64_test.go b/internal/wasm/jit/jit_arm64_test.go
index 68acdd98..fdd6e698 100644
--- a/internal/wasm/jit/jit_arm64_test.go
+++ b/internal/wasm/jit/jit_arm64_test.go
@@ -1,5 +1,3 @@
-//go:build arm64
-
 package jit
 
 import (
@@ -94,7 +92,7 @@ func TestArm64Compiler_returnFunction(t *testing.T) {
 		stackPointerToExpectedValue := map[uint64]uint32{}
 		for funcIndex := wasm.Index(0); funcIndex < callFrameNums; funcIndex++ {
 			// We have to do compilation in a separate subtest since each compilation takes
-			// the mutext lock and must release on the cleanup of each subtest.
+			// the mutex lock and must release on the cleanup of each subtest.
 			// TODO: delete after https://github.com/tetratelabs/wazero/issues/233
 			t.Run(fmt.Sprintf("compiling existing callframe %d", funcIndex), func(t *testing.T) {
 				// Each function pushes its funcaddr and soon returns.
@@ -1210,7 +1208,7 @@ func TestArm64Compiler_compileDrop(t *testing.T) {
 		// Plus, the top value must stay on a register.
 		top := compiler.locationStack.peek()
 		require.True(t, top.onRegister())
-		// Release the top value after drop so that we can verify the cpu itself is not mainpulated.
+		// Release the top value after drop so that we can verify the cpu itself is not manipulated.
 		err = compiler.compileReleaseRegisterToStack(top)
 		require.NoError(t, err)
 
@@ -1421,13 +1419,13 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 
 	for _, tc := range []struct {
 		name      string
-		setupFunc func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool)
+		setupFunc func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool)
 	}{
 		{
 			name: "cond on register",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				val := uint32(1)
-				if shoulGoElse {
+				if shouldGoElse {
 					val = 0
 				}
 				err := compiler.compileConstI32(&wazeroir.OperationConstI32{Value: val})
@@ -1436,9 +1434,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "LS",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(1), uint32(2)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1449,9 +1447,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "LE",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(1), uint32(2)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1462,9 +1460,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "HS",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(2), uint32(1)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1475,9 +1473,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "GE",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(2), uint32(1)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1488,9 +1486,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "HI",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(2), uint32(1)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1501,9 +1499,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "GT",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(2), uint32(1)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1514,9 +1512,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "LO",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(1), uint32(2)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1527,9 +1525,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "LT",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(1), uint32(2)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1540,9 +1538,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "MI",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := float32(1), float32(2)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2, x1 = x1, x2
 				}
 				requirePushTwoFloat32Consts(t, x1, x2, compiler)
@@ -1553,9 +1551,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "EQ",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(1), uint32(1)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2++
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1565,9 +1563,9 @@ func TestArm64Compiler_compileBrIf(t *testing.T) {
 		},
 		{
 			name: "NE",
-			setupFunc: func(t *testing.T, compiler *arm64Compiler, shoulGoElse bool) {
+			setupFunc: func(t *testing.T, compiler *arm64Compiler, shouldGoElse bool) {
 				x1, x2 := uint32(1), uint32(2)
-				if shoulGoElse {
+				if shouldGoElse {
 					x2 = x1
 				}
 				requirePushTwoInt32Consts(t, x1, x2, compiler)
@@ -1741,7 +1739,7 @@ func TestArm64Compiler_compileCall(t *testing.T) {
 				expectedValue += addTargetValue
 
 				// We have to do compilation in a separate subtest since each compilation takes
-				// the mutext lock and must release on the cleanup of each subtest.
+				// the mutex lock and must release on the cleanup of each subtest.
 				// TODO: delete after https://github.com/tetratelabs/wazero/issues/233
 				t.Run(fmt.Sprintf("compiling call target %d", i), func(t *testing.T) {
 					compiler := env.requireNewCompiler(t)
@@ -1831,14 +1829,14 @@ func TestArm64Compiler_compileCallIndirect(t *testing.T) {
 			Module: &wasm.ModuleInstance{Types: []*wasm.TypeInstance{{Type: &wasm.FunctionType{}}}},
 		}
 
-		// Place the offfset value.
+		// Place the offset value.
 		err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: 10})
 		require.NoError(t, err)
 
 		err = compiler.compileCallIndirect(targetOperation)
 		require.NoError(t, err)
 
-		// We expect to exit from the code in callIndirect so the subsequet code must be unreachable.
+		// We expect to exit from the code in callIndirect so the subsequent code must be unreachable.
 		err = compiler.compileExitFromNativeCode(jitCallStatusCodeUnreachable)
 		require.NoError(t, err)
 
@@ -1874,7 +1872,7 @@ func TestArm64Compiler_compileCallIndirect(t *testing.T) {
 		err = compiler.compileCallIndirect(targetOperation)
 		require.NoError(t, err)
 
-		// We expect to exit from the code in callIndirect so the subsequet code must be unreachable.
+		// We expect to exit from the code in callIndirect so the subsequent code must be unreachable.
 		err = compiler.compileExitFromNativeCode(jitCallStatusCodeUnreachable)
 		require.NoError(t, err)
 
@@ -1903,14 +1901,14 @@ func TestArm64Compiler_compileCallIndirect(t *testing.T) {
 		cf := &compiledFunction{source: &wasm.FunctionInstance{TypeID: 50}}
 		table[0] = uintptr(unsafe.Pointer(cf))
 
-		// Place the offfset value.
+		// Place the offset value.
 		err = compiler.compileConstI32(targetOffset)
 		require.NoError(t, err)
 
 		// Now emit the code.
 		require.NoError(t, compiler.compileCallIndirect(targetOperation))
 
-		// We expect to exit from the code in callIndirect so the subsequet code must be unreachable.
+		// We expect to exit from the code in callIndirect so the subsequent code must be unreachable.
 		err = compiler.compileExitFromNativeCode(jitCallStatusCodeUnreachable)
 		require.NoError(t, err)
 
@@ -1947,7 +1945,7 @@ func TestArm64Compiler_compileCallIndirect(t *testing.T) {
 					expectedReturnValue := uint32(i * 1000)
 
 					// We have to do compilation in a separate subtest since each compilation takes
-					// the mutext lock and must release on the cleanup of each subtest.
+					// the mutex lock and must release on the cleanup of each subtest.
 					// TODO: delete after https://github.com/tetratelabs/wazero/issues/233
 					t.Run(fmt.Sprintf("compiling call target for %d", i), func(t *testing.T) {
 						compiler := env.requireNewCompiler(t)
@@ -1986,7 +1984,7 @@ func TestArm64Compiler_compileCallIndirect(t *testing.T) {
 
 						compiler.f = &wasm.FunctionInstance{Module: moduleInstance, Kind: wasm.FunctionKindWasm}
 
-						// Place the offfset value. Here we try calling a function of functionaddr == table[i].FunctionIndex.
+						// Place the offset value. Here we try calling a function of functionaddr == table[i].FunctionIndex.
 						err = compiler.compileConstI32(&wazeroir.OperationConstI32{Value: uint32(i)})
 						require.NoError(t, err)
 
@@ -2135,7 +2133,6 @@ func TestArm64Compiler_compileSwap(t *testing.T) {
 }
 
 func TestArm64Compiler_compileModuleContextInitialization(t *testing.T) {
-	modEngine := &moduleEngine{compiledFunctions: make([]*compiledFunction, 100)}
 	for _, tc := range []struct {
 		name           string
 		moduleInstance *wasm.ModuleInstance
@@ -2143,7 +2140,6 @@ func TestArm64Compiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "no nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
 				Globals: []*wasm.GlobalInstance{{Val: 100}},
 				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Table:   &wasm.TableInstance{Table: make([]uintptr, 20)},
@@ -2152,7 +2148,6 @@ func TestArm64Compiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "globals nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine: modEngine,
 				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 10)},
 				Table:  &wasm.TableInstance{Table: make([]uintptr, 20)},
 			},
@@ -2160,7 +2155,6 @@ func TestArm64Compiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "memory nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
 				Globals: []*wasm.GlobalInstance{{Val: 100}},
 				Table:   &wasm.TableInstance{Table: make([]uintptr, 20)},
 			},
@@ -2168,41 +2162,35 @@ func TestArm64Compiler_compileModuleContextInitialization(t *testing.T) {
 		{
 			name: "table nil",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Table:   &wasm.TableInstance{Table: nil},
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
+				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 10)},
+				Table:  &wasm.TableInstance{Table: nil},
 			},
 		},
 		{
 			name: "table empty",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 10)},
-				Table:   &wasm.TableInstance{Table: make([]uintptr, 0)},
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
+				Table: &wasm.TableInstance{Table: make([]uintptr, 0)},
 			},
 		},
 		{
 			name: "memory zero length",
 			moduleInstance: &wasm.ModuleInstance{
-				Engine:  modEngine,
-				Globals: []*wasm.GlobalInstance{{Val: 100}},
-				Table:   &wasm.TableInstance{Table: make([]uintptr, 0)},
-				Memory:  &wasm.MemoryInstance{Buffer: make([]byte, 0)},
+				Memory: &wasm.MemoryInstance{Buffer: make([]byte, 0)},
 			},
 		},
 		{
-			name: "all nil except mod engine",
-			moduleInstance: &wasm.ModuleInstance{
-				Engine: modEngine,
-			},
+			name:           "all nil except mod engine",
+			moduleInstance: &wasm.ModuleInstance{},
 		},
 	} {
 		tc := tc
 		t.Run(tc.name, func(t *testing.T) {
 			env := newJITEnvironment()
+			ce := env.callEngine()
+
 			compiler := env.requireNewCompiler(t)
+			me := &moduleEngine{compiledFunctions: make([]*compiledFunction, 10)}
+			tc.moduleInstance.Engine = me
 			compiler.f.Module = tc.moduleInstance
 
 			// The assembler skips the first instruction so we intentionally add NOP here.
@@ -2226,8 +2214,6 @@ func TestArm64Compiler_compileModuleContextInitialization(t *testing.T) {
 			require.Equal(t, jitCallStatusCodeReturned, env.jitStatus())
 
 			// Check if the fields of callEngine.moduleContext are updated.
-			ce := env.callEngine()
-
 			bufSliceHeader := (*reflect.SliceHeader)(unsafe.Pointer(&tc.moduleInstance.Globals))
 			require.Equal(t, bufSliceHeader.Data, ce.moduleContext.globalElement0Address)
 
@@ -2243,7 +2229,7 @@ func TestArm64Compiler_compileModuleContextInitialization(t *testing.T) {
 				require.Equal(t, tableHeader.Data, ce.moduleContext.tableElement0Address)
 			}
 
-			require.Equal(t, uintptr(unsafe.Pointer(&modEngine.compiledFunctions[0])), ce.moduleContext.compiledFunctionsElement0Address)
+			require.Equal(t, uintptr(unsafe.Pointer(&me.compiledFunctions[0])), ce.moduleContext.compiledFunctionsElement0Address)
 		})
 	}
 }
@@ -2385,7 +2371,7 @@ func TestArm64Compiler_compileMemoryAccessOffsetSetup(t *testing.T) {
 
 					mem := env.memory()
 					if ceil := int64(base) + int64(offset) + int64(targetSizeInByte); int64(len(mem)) < ceil {
-						// If the targe memory region's ceil exceeds the length of memory, we must exit the function
+						// If the target memory region's ceil exceeds the length of memory, we must exit the function
 						// with jitCallStatusCodeMemoryOutOfBounds status code.
 						require.Equal(t, jitCallStatusCodeMemoryOutOfBounds, env.jitStatus())
 					} else {
@@ -2524,7 +2510,7 @@ func TestArm64Compiler_compileStore(t *testing.T) {
 			require.NoError(t, err)
 
 			// Set the value on the left and right neighboring memoryregion,
-			// so that we can veirfy the operation doesn't affect there.
+			// so that we can verify the operation doesn't affect there.
 			ceil := offset + tc.targetSizeInBytes
 			mem := env.memory()
 			expectedNeighbor8Bytes := uint64(0x12_34_56_78_9a_bc_ef_fe)
diff --git a/internal/wasm/memory_test.go b/internal/wasm/memory_test.go
index 425ee4f3..8ea2cdb6 100644
--- a/internal/wasm/memory_test.go
+++ b/internal/wasm/memory_test.go
@@ -40,7 +40,7 @@ func TestMemoryInstance_Grow_Size(t *testing.T) {
 		// so trying to grow two pages should result in failure.
 		require.Equal(t, int32(-1), int32(m.Grow(2)))
 		require.Equal(t, uint32(9), m.PageSize())
-		// But growing one page is still perimitted.
+		// But growing one page is still permitted.
 		require.Equal(t, uint32(9), m.Grow(1))
 		// Ensure that the current page size equals the max.
 		require.Equal(t, max, m.PageSize())
diff --git a/internal/wasm/module_test.go b/internal/wasm/module_test.go
index de40615e..676b6418 100644
--- a/internal/wasm/module_test.go
+++ b/internal/wasm/module_test.go
@@ -479,29 +479,6 @@ func TestModule_validateFunctions(t *testing.T) {
 	})
 }
 
-func TestModule_validateTable(t *testing.T) {
-	t.Run("invalid const expr", func(t *testing.T) {
-		m := Module{ElementSection: []*ElementSegment{{
-			OffsetExpr: &ConstantExpression{
-				Opcode: OpcodeUnreachable, // Invalid!
-			},
-		}}}
-		err := m.validateTable(&Table{}, nil)
-		require.Error(t, err)
-		require.EqualError(t, err, "invalid const expression for element: invalid opcode for const expression: 0x0")
-	})
-	t.Run("ok", func(t *testing.T) {
-		m := Module{ElementSection: []*ElementSegment{{
-			OffsetExpr: &ConstantExpression{
-				Opcode: OpcodeI32Const,
-				Data:   []byte{0x1},
-			},
-		}}}
-		err := m.validateTable(&Table{}, nil)
-		require.NoError(t, err)
-	})
-}
-
 func TestModule_validateMemory(t *testing.T) {
 	t.Run("data section exits but memory not declared", func(t *testing.T) {
 		m := Module{DataSection: make([]*DataSegment, 1)}
@@ -749,9 +726,3 @@ func TestModule_buildMemoryInstance(t *testing.T) {
 		require.Equal(t, max, *mem.Max)
 	})
 }
-
-func TestModule_buildTableInstance(t *testing.T) {
-	m := Module{TableSection: &Table{Min: 1}}
-	table := m.buildTable()
-	require.Equal(t, uint32(1), table.Min)
-}
diff --git a/internal/wasm/store_test.go b/internal/wasm/store_test.go
index 6bf639c4..48281ff6 100644
--- a/internal/wasm/store_test.go
+++ b/internal/wasm/store_test.go
@@ -439,7 +439,7 @@ func newStore() *Store {
 	return NewStore(context.Background(), &mockEngine{shouldCompileFail: false, callFailIndex: -1}, Features20191205)
 }
 
-func (e *mockEngine) Compile(_, _ []*FunctionInstance) (ModuleEngine, error) {
+func (e *mockEngine) NewModuleEngine(_, _ []*FunctionInstance) (ModuleEngine, error) {
 	if e.shouldCompileFail {
 		return nil, fmt.Errorf("some compilation error")
 	}
@@ -672,42 +672,6 @@ func TestStore_resolveImports(t *testing.T) {
 			require.EqualError(t, err, "import[0] global[test.target]: value type mismatch: f64 != i32")
 		})
 	})
-	t.Run("table", func(t *testing.T) {
-		t.Run("ok", func(t *testing.T) {
-			s := newStore()
-			max := uint32(10)
-			tableInst := &TableInstance{Max: &max}
-			s.modules[moduleName] = &ModuleInstance{Exports: map[string]*ExportInstance{name: {
-				Type:  ExternTypeTable,
-				Table: tableInst,
-			}}, Name: moduleName}
-			_, _, table, _, _, err := s.resolveImports(&Module{ImportSection: []*Import{{Module: moduleName, Name: name, Type: ExternTypeTable, DescTable: &Table{Max: &max}}}})
-			require.NoError(t, err)
-			require.Equal(t, table, tableInst)
-			require.Equal(t, 1, s.modules[moduleName].dependentCount)
-		})
-		t.Run("minimum size mismatch", func(t *testing.T) {
-			s := newStore()
-			importTableType := &Table{Min: 2}
-			s.modules[moduleName] = &ModuleInstance{Exports: map[string]*ExportInstance{name: {
-				Type:  ExternTypeTable,
-				Table: &TableInstance{Min: importTableType.Min - 1},
-			}}, Name: moduleName}
-			_, _, _, _, _, err := s.resolveImports(&Module{ImportSection: []*Import{{Module: moduleName, Name: name, Type: ExternTypeTable, DescTable: importTableType}}})
-			require.EqualError(t, err, "import[0] table[test.target]: minimum size mismatch: 2 > 1")
-		})
-		t.Run("maximum size mismatch", func(t *testing.T) {
-			s := newStore()
-			max := uint32(10)
-			importTableType := &Table{Max: &max}
-			s.modules[moduleName] = &ModuleInstance{Exports: map[string]*ExportInstance{name: {
-				Type:  ExternTypeTable,
-				Table: &TableInstance{Min: importTableType.Min - 1},
-			}}, Name: moduleName}
-			_, _, _, _, _, err := s.resolveImports(&Module{ImportSection: []*Import{{Module: moduleName, Name: name, Type: ExternTypeTable, DescTable: importTableType}}})
-			require.EqualError(t, err, "import[0] table[test.target]: maximum size mismatch: 10, but actual has no max")
-		})
-	})
 	t.Run("memory", func(t *testing.T) {
 		t.Run("ok", func(t *testing.T) {
 			s := newStore()
@@ -796,75 +760,6 @@ func TestModuleInstance_applyData(t *testing.T) {
 	require.Equal(t, []byte{0xa, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x5}, m.Memory.Buffer)
 }
 
-func TestModuleInstance_validateElements(t *testing.T) {
-	functionCounts := uint32(0xa)
-	m := &ModuleInstance{
-		Table:     &TableInstance{Table: make([]uintptr, 10)},
-		Functions: make([]*FunctionInstance, 10),
-	}
-	for _, tc := range []struct {
-		name     string
-		elements []*ElementSegment
-		expErr   bool
-	}{
-		{
-			name: "ok",
-			elements: []*ElementSegment{
-				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x0}}, Init: []uint32{0, functionCounts - 1}},
-			},
-		},
-		{
-			name: "ok on edge",
-			elements: []*ElementSegment{
-				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x8}}, Init: []uint32{0, functionCounts - 1}},
-			},
-		},
-		{
-			name: "out of bounds",
-			elements: []*ElementSegment{
-				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x9}}, Init: []uint32{0, functionCounts - 1}},
-			},
-			expErr: true,
-		},
-		{
-			name: "unknown function",
-			elements: []*ElementSegment{
-				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x0}}, Init: []uint32{0, functionCounts}},
-			},
-			expErr: true,
-		},
-	} {
-		tc := tc
-		t.Run(tc.name, func(t *testing.T) {
-			err := m.validateElements(tc.elements)
-			if tc.expErr {
-				require.Error(t, err)
-			} else {
-				require.NoError(t, err)
-			}
-		})
-	}
-}
-
-func TestModuleInstance_applyElements(t *testing.T) {
-	functionCounts := uint32(0xa)
-	m := &ModuleInstance{
-		Table:     &TableInstance{Table: make([]uintptr, 10)},
-		Functions: make([]*FunctionInstance, 10),
-		Engine:    &mockModuleEngine{},
-	}
-	targetIndex, targetOffset := uint32(1), byte(0)
-	targetIndex2, targetOffset2 := functionCounts-1, byte(0x8)
-	m.Functions[targetIndex] = &FunctionInstance{Type: &FunctionType{}, Index: Index(targetIndex)}
-	m.Functions[targetIndex2] = &FunctionInstance{Type: &FunctionType{}, Index: Index(targetIndex2)}
-	m.applyElements([]*ElementSegment{
-		{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{targetOffset}}, Init: []uint32{targetIndex}},
-		{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{targetOffset2}}, Init: []uint32{targetIndex2}},
-	})
-	require.Equal(t, uintptr(targetIndex), m.Table.Table[targetOffset])
-	require.Equal(t, uintptr(targetIndex2), m.Table.Table[targetOffset2])
-}
-
 func TestModuleInstance_decDependentCount(t *testing.T) {
 	count := 100
 	m := ModuleInstance{dependentCount: count}
diff --git a/internal/wasm/table_test.go b/internal/wasm/table_test.go
new file mode 100644
index 00000000..1d68f31b
--- /dev/null
+++ b/internal/wasm/table_test.go
@@ -0,0 +1,145 @@
+package internalwasm
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestStore_resolveImports_table(t *testing.T) {
+	const moduleName = "test"
+	const name = "target"
+
+	t.Run("ok", func(t *testing.T) {
+		s := newStore()
+		max := uint32(10)
+		tableInst := &TableInstance{Max: &max}
+		s.modules[moduleName] = &ModuleInstance{Exports: map[string]*ExportInstance{name: {
+			Type:  ExternTypeTable,
+			Table: tableInst,
+		}}, Name: moduleName}
+		_, _, table, _, _, err := s.resolveImports(&Module{ImportSection: []*Import{{Module: moduleName, Name: name, Type: ExternTypeTable, DescTable: &Table{Max: &max}}}})
+		require.NoError(t, err)
+		require.Equal(t, table, tableInst)
+		require.Equal(t, 1, s.modules[moduleName].dependentCount)
+	})
+	t.Run("minimum size mismatch", func(t *testing.T) {
+		s := newStore()
+		importTableType := &Table{Min: 2}
+		s.modules[moduleName] = &ModuleInstance{Exports: map[string]*ExportInstance{name: {
+			Type:  ExternTypeTable,
+			Table: &TableInstance{Min: importTableType.Min - 1},
+		}}, Name: moduleName}
+		_, _, _, _, _, err := s.resolveImports(&Module{ImportSection: []*Import{{Module: moduleName, Name: name, Type: ExternTypeTable, DescTable: importTableType}}})
+		require.EqualError(t, err, "import[0] table[test.target]: minimum size mismatch: 2 > 1")
+	})
+	t.Run("maximum size mismatch", func(t *testing.T) {
+		s := newStore()
+		max := uint32(10)
+		importTableType := &Table{Max: &max}
+		s.modules[moduleName] = &ModuleInstance{Exports: map[string]*ExportInstance{name: {
+			Type:  ExternTypeTable,
+			Table: &TableInstance{Min: importTableType.Min - 1},
+		}}, Name: moduleName}
+		_, _, _, _, _, err := s.resolveImports(&Module{ImportSection: []*Import{{Module: moduleName, Name: name, Type: ExternTypeTable, DescTable: importTableType}}})
+		require.EqualError(t, err, "import[0] table[test.target]: maximum size mismatch: 10, but actual has no max")
+	})
+}
+
+func TestModule_buildTableInstance(t *testing.T) {
+	m := Module{TableSection: &Table{Min: 1}}
+	table := m.buildTable()
+	require.Equal(t, uint32(1), table.Min)
+}
+
+func TestModule_validateTable(t *testing.T) {
+	t.Run("invalid const expr", func(t *testing.T) {
+		m := Module{ElementSection: []*ElementSegment{{
+			OffsetExpr: &ConstantExpression{
+				Opcode: OpcodeUnreachable, // Invalid!
+			},
+		}}}
+		err := m.validateTable(&Table{}, nil)
+		require.Error(t, err)
+		require.EqualError(t, err, "invalid const expression for element: invalid opcode for const expression: 0x0")
+	})
+	t.Run("ok", func(t *testing.T) {
+		m := Module{ElementSection: []*ElementSegment{{
+			OffsetExpr: &ConstantExpression{
+				Opcode: OpcodeI32Const,
+				Data:   []byte{0x1},
+			},
+		}}}
+		err := m.validateTable(&Table{}, nil)
+		require.NoError(t, err)
+	})
+}
+
+func TestModuleInstance_applyElements(t *testing.T) {
+	functionCounts := uint32(0xa)
+	m := &ModuleInstance{
+		Table:     &TableInstance{Table: make([]uintptr, 10)},
+		Functions: make([]*FunctionInstance, 10),
+		Engine:    &mockModuleEngine{},
+	}
+	targetIndex, targetOffset := uint32(1), byte(0)
+	targetIndex2, targetOffset2 := functionCounts-1, byte(0x8)
+	m.Functions[targetIndex] = &FunctionInstance{Type: &FunctionType{}, Index: Index(targetIndex)}
+	m.Functions[targetIndex2] = &FunctionInstance{Type: &FunctionType{}, Index: Index(targetIndex2)}
+	m.applyElements([]*ElementSegment{
+		{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{targetOffset}}, Init: []uint32{targetIndex}},
+		{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{targetOffset2}}, Init: []uint32{targetIndex2}},
+	})
+	require.Equal(t, uintptr(targetIndex), m.Table.Table[targetOffset])
+	require.Equal(t, uintptr(targetIndex2), m.Table.Table[targetOffset2])
+}
+
+func TestModuleInstance_validateElements(t *testing.T) {
+	functionCounts := uint32(0xa)
+	m := &ModuleInstance{
+		Table:     &TableInstance{Table: make([]uintptr, 10)},
+		Functions: make([]*FunctionInstance, 10),
+	}
+	for _, tc := range []struct {
+		name     string
+		elements []*ElementSegment
+		expErr   bool
+	}{
+		{
+			name: "ok",
+			elements: []*ElementSegment{
+				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x0}}, Init: []uint32{0, functionCounts - 1}},
+			},
+		},
+		{
+			name: "ok on edge",
+			elements: []*ElementSegment{
+				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x8}}, Init: []uint32{0, functionCounts - 1}},
+			},
+		},
+		{
+			name: "out of bounds",
+			elements: []*ElementSegment{
+				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x9}}, Init: []uint32{0, functionCounts - 1}},
+			},
+			expErr: true,
+		},
+		{
+			name: "unknown function",
+			elements: []*ElementSegment{
+				{OffsetExpr: &ConstantExpression{Opcode: OpcodeI32Const, Data: []byte{0x0}}, Init: []uint32{0, functionCounts}},
+			},
+			expErr: true,
+		},
+	} {
+		tc := tc
+		t.Run(tc.name, func(t *testing.T) {
+			err := m.validateElements(tc.elements)
+			if tc.expErr {
+				require.Error(t, err)
+			} else {
+				require.NoError(t, err)
+			}
+		})
+	}
+}
diff --git a/internal/wasm/text/index_namespace_test.go b/internal/wasm/text/index_namespace_test.go
index 080d04a2..21ac5e88 100644
--- a/internal/wasm/text/index_namespace_test.go
+++ b/internal/wasm/text/index_namespace_test.go
@@ -17,7 +17,7 @@ func TestIndexNamespace_SetId(t *testing.T) {
 	t.Run("set when empty", func(t *testing.T) {
 		id, err := in.setID([]byte("$x"))
 		require.NoError(t, err)
-		require.Equal(t, "x", id) // strins "$" to be like the name section
+		require.Equal(t, "x", id) // strips "$" to be like the name section
 		require.Equal(t, map[string]wasm.Index{"x": wasm.Index(0)}, in.idToIdx)
 	})
 	t.Run("set when exists fails", func(t *testing.T) {
diff --git a/tests/bench/testdata/case.go b/tests/bench/testdata/case.go
index 3a6884c8..676d2380 100644
--- a/tests/bench/testdata/case.go
+++ b/tests/bench/testdata/case.go
@@ -23,7 +23,7 @@ func allocateBuffer(size uint32) *byte {
 func getRandomStringRaw(retBufPtr **byte, retBufSize *int)
 
 // Get random string from the hosts.
-func getRandmString() string {
+func getRandomString() string {
 	var bufPtr *byte
 	var bufSize int
 	getRandomStringRaw(&bufPtr, &bufSize)
@@ -40,7 +40,7 @@ func base64OnString(num uint32) {
 	// Get random strings from the host and
 	// do base64 encoding them for given times.
 	for i := uint32(0); i < num; i++ {
-		msg := getRandmString()
+		msg := getRandomString()
 		_ = base64.StdEncoding.EncodeToString([]byte(msg))
 	}
 }