Repository: tetratelabs/wazero
Pull request #748 (2022-08-18 05:28:16)

Pass context into NewRuntime
Signed-off-by: Takeshi Yoneda <takeshi@tetrate.io>


Patch:
diff --git a/builder.go b/builder.go
index 2895a15e..d95b1cb4 100644
--- a/builder.go
+++ b/builder.go
@@ -15,7 +15,7 @@ import (
 // Ex. Below defines and instantiates a module named "env" with one function:
 //
 //	ctx := context.Background()
-//	r := wazero.NewRuntime()
+//	r := wazero.NewRuntime(ctx)
 //	defer r.Close(ctx) // This closes everything this Runtime created.
 //
 //	hello := func() {
@@ -198,7 +198,7 @@ type ModuleBuilder interface {
 	// Ex.
 	//
 	//	ctx := context.Background()
-	//	r := wazero.NewRuntime()
+	//	r := wazero.NewRuntime(ctx)
 	//	defer r.Close(ctx) // This closes everything this Runtime created.
 	//
 	//	hello := func() {
diff --git a/config.go b/config.go
index cee38053..2715566e 100644
--- a/config.go
+++ b/config.go
@@ -151,7 +151,7 @@ func NewRuntimeConfig() RuntimeConfig {
 type runtimeConfig struct {
 	enabledFeatures wasm.Features
 	isInterpreter   bool
-	newEngine       func(wasm.Features) wasm.Engine
+	newEngine       func(context.Context, wasm.Features) wasm.Engine
 }
 
 // engineLessConfig helps avoid copy/pasting the wrong defaults.
diff --git a/examples/allocation/rust/greet.go b/examples/allocation/rust/greet.go
index a5ffa748..0becb23d 100644
--- a/examples/allocation/rust/greet.go
+++ b/examples/allocation/rust/greet.go
@@ -25,7 +25,7 @@ func main() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// Instantiate a Go-defined module named "env" that exports a function to
diff --git a/examples/allocation/tinygo/greet.go b/examples/allocation/tinygo/greet.go
index d55fb6e0..c9ae7a8f 100644
--- a/examples/allocation/tinygo/greet.go
+++ b/examples/allocation/tinygo/greet.go
@@ -26,7 +26,7 @@ func main() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig().
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().
 		// Enable WebAssembly 2.0 support, which is required for TinyGo 0.24+.
 		WithWasmCore2())
 	defer r.Close(ctx) // This closes everything this Runtime created.
diff --git a/examples/allocation/zig/greet.go b/examples/allocation/zig/greet.go
index ac50652f..063e0e83 100644
--- a/examples/allocation/zig/greet.go
+++ b/examples/allocation/zig/greet.go
@@ -31,7 +31,7 @@ func run() error {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig().
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().
 		// Enable WebAssembly 2.0 support.
 		WithWasmCore2(),
 	)
diff --git a/examples/assemblyscript/assemblyscript.go b/examples/assemblyscript/assemblyscript.go
index c754e60c..4b743cdb 100644
--- a/examples/assemblyscript/assemblyscript.go
+++ b/examples/assemblyscript/assemblyscript.go
@@ -28,7 +28,7 @@ func main() {
 
 	// Create a new WebAssembly Runtime.
 	// Use WebAssembly 2.0 because AssemblyScript uses some >1.0 features.
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig().
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().
 		WithWasmCore2())
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
diff --git a/examples/basic/add.go b/examples/basic/add.go
index 108a328b..19d34912 100644
--- a/examples/basic/add.go
+++ b/examples/basic/add.go
@@ -24,7 +24,7 @@ func main() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// Add a module to the runtime named "wasm/math" which exports one function "add", implemented in WebAssembly.
diff --git a/examples/import-go/age-calculator.go b/examples/import-go/age-calculator.go
index 5bc4b96d..08ae25a2 100644
--- a/examples/import-go/age-calculator.go
+++ b/examples/import-go/age-calculator.go
@@ -28,7 +28,7 @@ func main() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// Instantiate a Go-defined module named "env" that exports functions to
diff --git a/examples/multiple-results/multiple-results.go b/examples/multiple-results/multiple-results.go
index 61db2600..00a6eb8c 100644
--- a/examples/multiple-results/multiple-results.go
+++ b/examples/multiple-results/multiple-results.go
@@ -34,7 +34,7 @@ func main() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// Add a module that uses offset parameters for multiple results defined in WebAssembly.
@@ -45,7 +45,7 @@ func main() {
 
 	// wazero enables WebAssembly 1.0 by default. Opt-in to other features:
 	runtimeWithMultiValue := wazero.NewRuntimeWithConfig(
-		wazero.NewRuntimeConfig().WithFeatureMultiValue(true),
+		ctx, wazero.NewRuntimeConfig().WithFeatureMultiValue(true),
 		// ^^ Note: WebAssembly 2.0 (WithWasmCore2) includes "multi-value".
 	)
 
diff --git a/examples/namespace/counter.go b/examples/namespace/counter.go
index 9ac8320e..c5feb749 100644
--- a/examples/namespace/counter.go
+++ b/examples/namespace/counter.go
@@ -25,7 +25,7 @@ func main() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// Compile WebAssembly that requires its own "env" module.
diff --git a/examples/wasi/cat.go b/examples/wasi/cat.go
index 2da57ccb..0ce765d6 100644
--- a/examples/wasi/cat.go
+++ b/examples/wasi/cat.go
@@ -43,7 +43,7 @@ func main() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig().
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfig().
 		// Enable WebAssembly 2.0 support, which is required for TinyGo 0.24+.
 		WithWasmCore2())
 	defer r.Close(ctx) // This closes everything this Runtime created.
diff --git a/internal/engine/compiler/engine.go b/internal/engine/compiler/engine.go
index 777e504f..106d0fdf 100644
--- a/internal/engine/compiler/engine.go
+++ b/internal/engine/compiler/engine.go
@@ -590,11 +590,11 @@ func (e *moduleEngine) Call(ctx context.Context, callCtx *wasm.CallContext, f *w
 	return
 }
 
-func NewEngine(enabledFeatures wasm.Features) wasm.Engine {
-	return newEngine(enabledFeatures)
+func NewEngine(ctx context.Context, enabledFeatures wasm.Features) wasm.Engine {
+	return newEngine(ctx, enabledFeatures)
 }
 
-func newEngine(enabledFeatures wasm.Features) *engine {
+func newEngine(_ context.Context, enabledFeatures wasm.Features) *engine {
 	return &engine{
 		enabledFeatures: enabledFeatures,
 		codes:           map[wasm.ModuleID][]*code{},
diff --git a/internal/engine/interpreter/interpreter.go b/internal/engine/interpreter/interpreter.go
index 2ec06210..da2e98b2 100644
--- a/internal/engine/interpreter/interpreter.go
+++ b/internal/engine/interpreter/interpreter.go
@@ -29,7 +29,7 @@ type engine struct {
 	mux             sync.RWMutex
 }
 
-func NewEngine(enabledFeatures wasm.Features) wasm.Engine {
+func NewEngine(_ context.Context, enabledFeatures wasm.Features) wasm.Engine {
 	return &engine{
 		enabledFeatures: enabledFeatures,
 		codes:           map[wasm.ModuleID][]*code{},
diff --git a/runtime.go b/runtime.go
index 33884f6e..90138930 100644
--- a/runtime.go
+++ b/runtime.go
@@ -16,7 +16,7 @@ import (
 // Ex. The below is the basic initialization of wazero's WebAssembly Runtime.
 //
 //	ctx := context.Background()
-//	r := wazero.NewRuntime()
+//	r := wazero.NewRuntime(ctx)
 //	defer r.Close(ctx) // This closes everything this Runtime created.
 //
 //	module, _ := r.InstantiateModuleFromBinary(ctx, wasm)
@@ -52,7 +52,7 @@ type Runtime interface {
 	//
 	// Ex.
 	//	ctx := context.Background()
-	//	r := wazero.NewRuntime()
+	//	r := wazero.NewRuntime(ctx)
 	//	defer r.Close(ctx) // This closes everything this Runtime created.
 	//
 	//	module, _ := r.InstantiateModuleFromBinary(ctx, wasm)
@@ -107,7 +107,7 @@ type Runtime interface {
 	//
 	// Ex.
 	//	ctx := context.Background()
-	//	r := wazero.NewRuntime()
+	//	r := wazero.NewRuntime(ctx)
 	//	defer r.CloseWithExitCode(ctx, 2) // This closes everything this Runtime created.
 	//
 	//	// Everything below here can be closed, but will anyway due to above.
@@ -120,14 +120,14 @@ type Runtime interface {
 }
 
 // NewRuntime returns a runtime with a configuration assigned by NewRuntimeConfig.
-func NewRuntime() Runtime {
-	return NewRuntimeWithConfig(NewRuntimeConfig())
+func NewRuntime(ctx context.Context) Runtime {
+	return NewRuntimeWithConfig(ctx, NewRuntimeConfig())
 }
 
 // NewRuntimeWithConfig returns a runtime with the given configuration.
-func NewRuntimeWithConfig(rConfig RuntimeConfig) Runtime {
+func NewRuntimeWithConfig(ctx context.Context, rConfig RuntimeConfig) Runtime {
 	config := rConfig.(*runtimeConfig)
-	store, ns := wasm.NewStore(config.enabledFeatures, config.newEngine(config.enabledFeatures))
+	store, ns := wasm.NewStore(config.enabledFeatures, config.newEngine(ctx, config.enabledFeatures))
 	return &runtime{
 		store:           store,
 		ns:              &namespace{store: store, ns: ns},
diff --git a/wasi_snapshot_preview1/wasi.go b/wasi_snapshot_preview1/wasi.go
index b65b33ce..7ec7841e 100644
--- a/wasi_snapshot_preview1/wasi.go
+++ b/wasi_snapshot_preview1/wasi.go
@@ -7,7 +7,7 @@
 // "wasi_snapshot_preview1", Otherwise, it will error due to missing imports.
 //
 //	ctx := context.Background()
-//	r := wazero.NewRuntime()
+//	r := wazero.NewRuntime(ctx)
 //	defer r.Close(ctx) // This closes everything this Runtime created.
 //
 //	_, _ = Instantiate(ctx, r)


Test patch:
diff --git a/assemblyscript/assemblyscript_example_test.go b/assemblyscript/assemblyscript_example_test.go
index b4d2c276..62f2c44a 100644
--- a/assemblyscript/assemblyscript_example_test.go
+++ b/assemblyscript/assemblyscript_example_test.go
@@ -13,7 +13,7 @@ import (
 func Example_instantiate() {
 	ctx := context.Background()
 
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// This adds the "env" module to the runtime, with AssemblyScript's special
@@ -30,7 +30,7 @@ func Example_instantiate() {
 func Example_functionExporter() {
 	ctx := context.Background()
 
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// First construct your own module builder for "env"
diff --git a/assemblyscript/assemblyscript_test.go b/assemblyscript/assemblyscript_test.go
index 7f10dcfe..8a105bfa 100644
--- a/assemblyscript/assemblyscript_test.go
+++ b/assemblyscript/assemblyscript_test.go
@@ -422,7 +422,7 @@ func requireProxyModule(t *testing.T, fns FunctionExporter, config wazero.Module
 	// Set context to one that has an experimental listener
 	ctx := context.WithValue(testCtx, FunctionListenerFactoryKey{}, logging.NewLoggingListenerFactory(&log))
 
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
 
 	builder := r.NewModuleBuilder("env")
 	fns.ExportFunctions(builder)
diff --git a/builder_test.go b/builder_test.go
index 5b75bef7..22bae5ac 100644
--- a/builder_test.go
+++ b/builder_test.go
@@ -360,7 +360,7 @@ func TestNewModuleBuilder_Compile(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			b := tc.input(NewRuntime()).(*moduleBuilder)
+			b := tc.input(NewRuntime(testCtx)).(*moduleBuilder)
 			compiled, err := b.Compile(testCtx, NewCompileConfig())
 			require.NoError(t, err)
 			m := compiled.(*compiledModule)
@@ -412,7 +412,7 @@ func TestNewModuleBuilder_Compile_Errors(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			_, e := tc.input(NewRuntime()).Compile(testCtx, tc.config)
+			_, e := tc.input(NewRuntime(testCtx)).Compile(testCtx, tc.config)
 			require.EqualError(t, e, tc.expectedErr)
 		})
 	}
@@ -420,7 +420,7 @@ func TestNewModuleBuilder_Compile_Errors(t *testing.T) {
 
 // TestNewModuleBuilder_Instantiate ensures Runtime.InstantiateModule is called on success.
 func TestNewModuleBuilder_Instantiate(t *testing.T) {
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	m, err := r.NewModuleBuilder("env").Instantiate(testCtx, r)
 	require.NoError(t, err)
 
@@ -434,7 +434,7 @@ func TestNewModuleBuilder_Instantiate(t *testing.T) {
 
 // TestNewModuleBuilder_Instantiate_Errors ensures errors propagate from Runtime.InstantiateModule
 func TestNewModuleBuilder_Instantiate_Errors(t *testing.T) {
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	_, err := r.NewModuleBuilder("env").Instantiate(testCtx, r)
 	require.NoError(t, err)
 
diff --git a/emscripten/emscripten_example_test.go b/emscripten/emscripten_example_test.go
index eb41bc4d..8afe71ef 100644
--- a/emscripten/emscripten_example_test.go
+++ b/emscripten/emscripten_example_test.go
@@ -14,7 +14,7 @@ import (
 func Example_instantiate() {
 	ctx := context.Background()
 
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// Add WASI which is typically required when using Emscripten.
@@ -35,7 +35,7 @@ func Example_instantiate() {
 func Example_functionExporter() {
 	ctx := context.Background()
 
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	// Add WASI which is typically required when using Emscripten.
diff --git a/emscripten/emscripten_test.go b/emscripten/emscripten_test.go
index e46f2401..6efaf473 100644
--- a/emscripten/emscripten_test.go
+++ b/emscripten/emscripten_test.go
@@ -29,7 +29,7 @@ func TestGrow(t *testing.T) {
 	// Set context to one that has an experimental listener
 	ctx := context.WithValue(testCtx, FunctionListenerFactoryKey{}, logging.NewLoggingListenerFactory(&log))
 
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
 	defer r.Close(ctx)
 
 	_, err := wasi_snapshot_preview1.Instantiate(ctx, r)
diff --git a/example_test.go b/example_test.go
index 39c01b74..892d9b2d 100644
--- a/example_test.go
+++ b/example_test.go
@@ -22,7 +22,7 @@ func Example() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := NewRuntime()
+	r := NewRuntime(ctx)
 
 	// Add a module to the runtime named "wasm/math" which exports one function
 	// "add", implemented in WebAssembly.
diff --git a/experimental/fs_example_test.go b/experimental/fs_example_test.go
index 716a8eac..d7d55b31 100644
--- a/experimental/fs_example_test.go
+++ b/experimental/fs_example_test.go
@@ -24,7 +24,7 @@ var fsWasm []byte
 func Example_withFS() {
 	ctx := context.Background()
 
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	if _, err := wasi_snapshot_preview1.Instantiate(ctx, r); err != nil {
diff --git a/experimental/listener_example_test.go b/experimental/listener_example_test.go
index 5fe921e3..5f0b9aa1 100644
--- a/experimental/listener_example_test.go
+++ b/experimental/listener_example_test.go
@@ -58,7 +58,7 @@ func Example_customListenerFactory() {
 	// Set context to one that has an experimental listener
 	ctx := context.WithValue(context.Background(), FunctionListenerFactoryKey{}, u)
 
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	if _, err := wasi_snapshot_preview1.Instantiate(ctx, r); err != nil {
diff --git a/experimental/listener_test.go b/experimental/listener_test.go
index ba85d745..dedc8319 100644
--- a/experimental/listener_test.go
+++ b/experimental/listener_test.go
@@ -51,7 +51,7 @@ func TestFunctionListenerFactory(t *testing.T) {
 
 	if platform.CompilerSupported() {
 		t.Run("fails on compile if compiler", func(t *testing.T) {
-			r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigCompiler())
+			r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigCompiler())
 			defer r.Close(testCtx) // This closes everything this Runtime created.
 			_, err := r.CompileModule(ctx, bin, wazero.NewCompileConfig())
 			require.EqualError(t, err,
@@ -59,7 +59,7 @@ func TestFunctionListenerFactory(t *testing.T) {
 		})
 	}
 
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	_, err := r.CompileModule(ctx, bin, wazero.NewCompileConfig())
diff --git a/experimental/logging/log_listener_example_test.go b/experimental/logging/log_listener_example_test.go
index 7c1f4880..4462c985 100644
--- a/experimental/logging/log_listener_example_test.go
+++ b/experimental/logging/log_listener_example_test.go
@@ -24,7 +24,7 @@ func Example_newLoggingListenerFactory() {
 	// Set context to one that has an experimental listener
 	ctx := context.WithValue(context.Background(), experimental.FunctionListenerFactoryKey{}, logging.NewLoggingListenerFactory(os.Stdout))
 
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
 	defer r.Close(ctx) // This closes everything this Runtime created.
 
 	if _, err := wasi_snapshot_preview1.Instantiate(ctx, r); err != nil {
diff --git a/internal/engine/compiler/engine_test.go b/internal/engine/compiler/engine_test.go
index c22dc094..bde9a885 100644
--- a/internal/engine/compiler/engine_test.go
+++ b/internal/engine/compiler/engine_test.go
@@ -35,7 +35,7 @@ func (e *engineTester) ListenerFactory() experimental.FunctionListenerFactory {
 
 // NewEngine implements the same method as documented on enginetest.EngineTester.
 func (e *engineTester) NewEngine(enabledFeatures wasm.Features) wasm.Engine {
-	return newEngine(enabledFeatures)
+	return newEngine(context.Background(), enabledFeatures)
 }
 
 // InitTables implements the same method as documented on enginetest.EngineTester.
@@ -187,7 +187,7 @@ func TestCompiler_Releasecode_Panic(t *testing.T) {
 // See comments on initialValueStackSize and initialCallFrameStackSize.
 func TestCompiler_SliceAllocatedOnHeap(t *testing.T) {
 	enabledFeatures := wasm.Features20191205
-	e := newEngine(enabledFeatures)
+	e := newEngine(context.Background(), enabledFeatures)
 	s, ns := wasm.NewStore(enabledFeatures, e)
 
 	const hostModuleName = "env"
@@ -286,7 +286,7 @@ func TestCompiler_SliceAllocatedOnHeap(t *testing.T) {
 
 // TODO: move most of this logic to enginetest.go so that there is less drift between interpreter and compiler
 func TestEngine_Cachedcodes(t *testing.T) {
-	e := newEngine(wasm.Features20191205)
+	e := newEngine(context.Background(), wasm.Features20191205)
 	exp := []*code{
 		{codeSegment: []byte{0x0}},
 		{codeSegment: []byte{0x0}},
diff --git a/internal/engine/interpreter/interpreter_test.go b/internal/engine/interpreter/interpreter_test.go
index 2f83da94..383d809f 100644
--- a/internal/engine/interpreter/interpreter_test.go
+++ b/internal/engine/interpreter/interpreter_test.go
@@ -83,7 +83,7 @@ func (e engineTester) ListenerFactory() experimental.FunctionListenerFactory {
 
 // NewEngine implements enginetest.EngineTester NewEngine.
 func (e engineTester) NewEngine(enabledFeatures wasm.Features) wasm.Engine {
-	return NewEngine(enabledFeatures)
+	return NewEngine(context.Background(), enabledFeatures)
 }
 
 // InitTables implements enginetest.EngineTester InitTables.
diff --git a/internal/integration_test/bench/bench_test.go b/internal/integration_test/bench/bench_test.go
index 7db14e27..bf3634ba 100644
--- a/internal/integration_test/bench/bench_test.go
+++ b/internal/integration_test/bench/bench_test.go
@@ -180,7 +180,7 @@ func createRuntime(b *testing.B, config wazero.RuntimeConfig) wazero.Runtime {
 		m.Memory().Write(ctx, offset, b)
 	}
 
-	r := wazero.NewRuntimeWithConfig(config)
+	r := wazero.NewRuntimeWithConfig(testCtx, config)
 
 	_, err := r.NewModuleBuilder("env").
 		ExportFunction("get_random_string", getRandomString).
diff --git a/internal/integration_test/bench/codec_test.go b/internal/integration_test/bench/codec_test.go
index 47341a5c..656d29a5 100644
--- a/internal/integration_test/bench/codec_test.go
+++ b/internal/integration_test/bench/codec_test.go
@@ -94,7 +94,7 @@ func TestExampleUpToDate(t *testing.T) {
 	})
 
 	t.Run("Executable", func(t *testing.T) {
-		r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig().WithWasmCore2())
+		r := wazero.NewRuntimeWithConfig(testCtx, wazero.NewRuntimeConfig().WithWasmCore2())
 
 		// Add WASI to satisfy import tests
 		wm, err := wasi_snapshot_preview1.Instantiate(testCtx, r)
diff --git a/internal/integration_test/engine/adhoc_test.go b/internal/integration_test/engine/adhoc_test.go
index 8c0428cf..119b9eb9 100644
--- a/internal/integration_test/engine/adhoc_test.go
+++ b/internal/integration_test/engine/adhoc_test.go
@@ -67,7 +67,7 @@ func runAllTests(t *testing.T, tests map[string]func(t *testing.T, r wazero.Runt
 		testf := testf // pin
 		t.Run(name, func(t *testing.T) {
 			t.Parallel()
-			testf(t, wazero.NewRuntimeWithConfig(config))
+			testf(t, wazero.NewRuntimeWithConfig(testCtx, config))
 		})
 	}
 }
diff --git a/internal/integration_test/fs/fs_test.go b/internal/integration_test/fs/fs_test.go
index 8fab1a96..18d6b205 100644
--- a/internal/integration_test/fs/fs_test.go
+++ b/internal/integration_test/fs/fs_test.go
@@ -149,7 +149,7 @@ func (f *wasiFile) Seek(offset int64, whence int) (int64, error) {
 }
 
 func TestReader(t *testing.T) {
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	_, err := wasi_snapshot_preview1.Instantiate(testCtx, r)
diff --git a/internal/integration_test/fuzzcases/fuzzcases_test.go b/internal/integration_test/fuzzcases/fuzzcases_test.go
index aa813b0b..efce2a3b 100644
--- a/internal/integration_test/fuzzcases/fuzzcases_test.go
+++ b/internal/integration_test/fuzzcases/fuzzcases_test.go
@@ -28,7 +28,7 @@ func runWithCompiler(t *testing.T, runner func(t *testing.T, r wazero.Runtime))
 		return
 	}
 	t.Run("compiler", func(t *testing.T) {
-		r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigCompiler().WithWasmCore2())
+		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigCompiler().WithWasmCore2())
 		defer r.Close(ctx)
 		runner(t, r)
 	})
@@ -36,7 +36,7 @@ func runWithCompiler(t *testing.T, runner func(t *testing.T, r wazero.Runtime))
 
 func runWithInterpreter(t *testing.T, runner func(t *testing.T, r wazero.Runtime)) {
 	t.Run("interpreter", func(t *testing.T) {
-		r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter().WithWasmCore2())
+		r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter().WithWasmCore2())
 		defer r.Close(ctx)
 		runner(t, r)
 	})
diff --git a/internal/integration_test/spectest/spectest.go b/internal/integration_test/spectest/spectest.go
index a01c08fe..e8b230ca 100644
--- a/internal/integration_test/spectest/spectest.go
+++ b/internal/integration_test/spectest/spectest.go
@@ -417,7 +417,7 @@ func maybeSetMemoryCap(mod *wasm.Module) {
 
 // Run runs all the test inside the testDataFS file system where all the cases are described
 // via JSON files created from wast2json.
-func Run(t *testing.T, testDataFS embed.FS, newEngine func(wasm.Features) wasm.Engine, enabledFeatures wasm.Features) {
+func Run(t *testing.T, testDataFS embed.FS, newEngine func(context.Context, wasm.Features) wasm.Engine, enabledFeatures wasm.Features) {
 	files, err := testDataFS.ReadDir("testdata")
 	require.NoError(t, err)
 
@@ -443,7 +443,7 @@ func Run(t *testing.T, testDataFS embed.FS, newEngine func(wasm.Features) wasm.E
 		wastName := basename(base.SourceFile)
 
 		t.Run(wastName, func(t *testing.T) {
-			s, ns := wasm.NewStore(enabledFeatures, newEngine(enabledFeatures))
+			s, ns := wasm.NewStore(enabledFeatures, newEngine(testCtx, enabledFeatures))
 			addSpectestModule(t, s, ns)
 
 			var lastInstantiatedModuleName string
diff --git a/internal/integration_test/vs/runtime.go b/internal/integration_test/vs/runtime.go
index 4c2e0187..803001d3 100644
--- a/internal/integration_test/vs/runtime.go
+++ b/internal/integration_test/vs/runtime.go
@@ -79,7 +79,7 @@ func (r *wazeroRuntime) log(ctx context.Context, m api.Module, offset, byteCount
 }
 
 func (r *wazeroRuntime) Compile(ctx context.Context, cfg *RuntimeConfig) (err error) {
-	r.runtime = wazero.NewRuntimeWithConfig(r.config)
+	r.runtime = wazero.NewRuntimeWithConfig(ctx, r.config)
 	if cfg.LogFn != nil {
 		r.logFn = cfg.LogFn
 		if r.env, err = r.runtime.NewModuleBuilder("env").
diff --git a/internal/testing/modgen/modgen_test.go b/internal/testing/modgen/modgen_test.go
index c3d926a3..df00a750 100644
--- a/internal/testing/modgen/modgen_test.go
+++ b/internal/testing/modgen/modgen_test.go
@@ -28,7 +28,7 @@ const (
 func TestModGen(t *testing.T) {
 	tested := map[string]struct{}{}
 	rand := rand.New(rand.NewSource(0)) // use deterministic seed source for easy debugging.
-	runtime := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfig().WithWasmCore2())
+	runtime := wazero.NewRuntimeWithConfig(testCtx, wazero.NewRuntimeConfig().WithWasmCore2())
 	for _, size := range []int{1, 2, 5, 10, 50, 100} {
 		for i := 0; i < 100; i++ {
 			seed := make([]byte, size)
diff --git a/namespace_test.go b/namespace_test.go
index ab92971a..12012c67 100644
--- a/namespace_test.go
+++ b/namespace_test.go
@@ -9,7 +9,7 @@ import (
 
 // TestRuntime_Namespace ensures namespaces are independent.
 func TestRuntime_Namespace(t *testing.T) {
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	// Compile a module to add to the runtime
diff --git a/runtime_test.go b/runtime_test.go
index d48b4d83..15a41b81 100644
--- a/runtime_test.go
+++ b/runtime_test.go
@@ -42,7 +42,7 @@ func TestRuntime_CompileModule(t *testing.T) {
 		},
 	}
 
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	for _, tt := range tests {
@@ -123,7 +123,7 @@ func TestRuntime_CompileModule_Errors(t *testing.T) {
 		},
 	}
 
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	for _, tt := range tests {
@@ -168,7 +168,7 @@ func TestModule_Memory(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			r := NewRuntime()
+			r := NewRuntime(testCtx)
 			defer r.Close(testCtx)
 
 			// Instantiate the module and get the export of the above memory
@@ -239,7 +239,7 @@ func TestModule_Global(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			r := NewRuntime().(*runtime)
+			r := NewRuntime(testCtx).(*runtime)
 			defer r.Close(testCtx)
 
 			var m CompiledModule
@@ -275,7 +275,7 @@ func TestModule_Global(t *testing.T) {
 }
 
 func TestRuntime_InstantiateModule_UsesContext(t *testing.T) {
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	// Define a function that will be set as the start function
@@ -318,7 +318,7 @@ func TestRuntime_InstantiateModule_UsesContext(t *testing.T) {
 // TestRuntime_InstantiateModuleFromBinary_DoesntEnforce_Start ensures wapc-go work when modules import WASI, but don't
 // export "_start".
 func TestRuntime_InstantiateModuleFromBinary_DoesntEnforce_Start(t *testing.T) {
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	binary := binaryformat.EncodeModule(&wasm.Module{
@@ -355,7 +355,7 @@ func TestRuntime_InstantiateModuleFromBinary_ErrorOnStart(t *testing.T) {
 		tc := tt
 
 		t.Run(tc.name, func(t *testing.T) {
-			r := NewRuntime()
+			r := NewRuntime(testCtx)
 			defer r.Close(testCtx)
 
 			start := func(context.Context) {
@@ -383,7 +383,7 @@ func TestRuntime_InstantiateModuleFromBinary_ErrorOnStart(t *testing.T) {
 // TestRuntime_InstantiateModule_WithName tests that we can pre-validate (cache) a module and instantiate it under
 // different names. This pattern is used in wapc-go.
 func TestRuntime_InstantiateModule_WithName(t *testing.T) {
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	base, err := r.CompileModule(testCtx, binaryNamedZero, NewCompileConfig())
@@ -407,7 +407,7 @@ func TestRuntime_InstantiateModule_WithName(t *testing.T) {
 }
 
 func TestRuntime_InstantiateModule_ExitError(t *testing.T) {
-	r := NewRuntime()
+	r := NewRuntime(testCtx)
 	defer r.Close(testCtx)
 
 	start := func(ctx context.Context, m api.Module) {
@@ -463,7 +463,7 @@ func TestRuntime_CloseWithExitCode(t *testing.T) {
 	for _, tt := range tests {
 		tc := tt
 		t.Run(tc.name, func(t *testing.T) {
-			r := NewRuntime()
+			r := NewRuntime(testCtx)
 
 			code, err := r.CompileModule(testCtx, bin, NewCompileConfig())
 			require.NoError(t, err)
@@ -505,10 +505,10 @@ func TestRuntime_CloseWithExitCode(t *testing.T) {
 func TestRuntime_Close_ClosesCompiledModules(t *testing.T) {
 	engine := &mockEngine{name: "mock", cachedModules: map[*wasm.Module]struct{}{}}
 	conf := *engineLessConfig
-	conf.newEngine = func(wasm.Features) wasm.Engine {
+	conf.newEngine = func(context.Context, wasm.Features) wasm.Engine {
 		return engine
 	}
-	r := NewRuntimeWithConfig(&conf)
+	r := NewRuntimeWithConfig(testCtx, &conf)
 	defer r.Close(testCtx)
 
 	// Normally compiled modules are closed when instantiated but this is never instantiated.
diff --git a/wasi_snapshot_preview1/example_test.go b/wasi_snapshot_preview1/example_test.go
index 3e9f7028..6350a7c9 100644
--- a/wasi_snapshot_preview1/example_test.go
+++ b/wasi_snapshot_preview1/example_test.go
@@ -26,7 +26,7 @@ func Example() {
 	ctx := context.Background()
 
 	// Create a new WebAssembly Runtime.
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(ctx)
 
 	// Instantiate WASI, which implements system I/O such as console output.
 	wm, err := Instantiate(ctx, r)
diff --git a/wasi_snapshot_preview1/usage_test.go b/wasi_snapshot_preview1/usage_test.go
index 557dc927..f05dd286 100644
--- a/wasi_snapshot_preview1/usage_test.go
+++ b/wasi_snapshot_preview1/usage_test.go
@@ -15,7 +15,7 @@ import (
 var wasiArg []byte
 
 func TestInstantiateModule(t *testing.T) {
-	r := wazero.NewRuntime()
+	r := wazero.NewRuntime(testCtx)
 
 	stdout := bytes.NewBuffer(nil)
 
diff --git a/wasi_snapshot_preview1/wasi_bench_test.go b/wasi_snapshot_preview1/wasi_bench_test.go
index 1e9dd270..42136503 100644
--- a/wasi_snapshot_preview1/wasi_bench_test.go
+++ b/wasi_snapshot_preview1/wasi_bench_test.go
@@ -37,7 +37,7 @@ func Test_Benchmark_EnvironGet(t *testing.T) {
 }
 
 func Benchmark_EnvironGet(b *testing.B) {
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(testCtx, wazero.NewRuntimeConfigInterpreter())
 
 	compiled, err := r.NewModuleBuilder(b.Name()).
 		ExportMemoryWithMax("memory", 1, 1).
diff --git a/wasi_snapshot_preview1/wasi_test.go b/wasi_snapshot_preview1/wasi_test.go
index 02d1843c..550396c2 100644
--- a/wasi_snapshot_preview1/wasi_test.go
+++ b/wasi_snapshot_preview1/wasi_test.go
@@ -32,7 +32,7 @@ func requireProxyModule(t *testing.T, config wazero.ModuleConfig) (api.Module, a
 	// Set context to one that has an experimental listener
 	ctx := context.WithValue(testCtx, FunctionListenerFactoryKey{}, logging.NewLoggingListenerFactory(&log))
 
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
 
 	wasiModuleCompiled, err := (&builder{r}).moduleBuilder().
 		Compile(ctx, wazero.NewCompileConfig())
@@ -61,7 +61,7 @@ func requireErrnoNosys(t *testing.T, funcName string, params ...uint64) string {
 	// Set context to one that has an experimental listener
 	ctx := context.WithValue(testCtx, FunctionListenerFactoryKey{}, logging.NewLoggingListenerFactory(&log))
 
-	r := wazero.NewRuntimeWithConfig(wazero.NewRuntimeConfigInterpreter())
+	r := wazero.NewRuntimeWithConfig(ctx, wazero.NewRuntimeConfigInterpreter())
 	defer r.Close(ctx)
 
 	// Instantiate the wasi module.