wa-lang.org/wazero@v1.0.2/imports/go/gojs.go (about) 1 // Package gojs allows you to run wasm binaries compiled by Go when `GOOS=js` 2 // and `GOARCH=wasm`. See https://wazero.io/languages/go/ for more. 3 // 4 // # Experimental 5 // 6 // Go defines js "EXPERIMENTAL... exempt from the Go compatibility promise." 7 // Accordingly, wazero cannot guarantee this will work from release to release, 8 // or that usage will be relatively free of bugs. Due to this and the 9 // relatively high implementation overhead, most will choose TinyGo instead. 10 package gojs 11 12 import ( 13 "context" 14 "net/http" 15 16 "wa-lang.org/wazero" 17 . "wa-lang.org/wazero/internal/gojs" 18 "wa-lang.org/wazero/internal/wasm" 19 ) 20 21 // WithRoundTripper sets the http.RoundTripper used to Run Wasm. 22 // 23 // For example, if the code compiled via `GOARCH=wasm GOOS=js` uses 24 // http.RoundTripper, you can avoid failures by assigning an implementation 25 // like so: 26 // 27 // ctx = gojs.WithRoundTripper(ctx, http.DefaultTransport) 28 // err = gojs.Run(ctx, r, compiled, config) 29 func WithRoundTripper(ctx context.Context, rt http.RoundTripper) context.Context { 30 return context.WithValue(ctx, RoundTripperKey{}, rt) 31 } 32 33 // Run instantiates a new module and calls "run" with the given config. 34 // 35 // # Parameters 36 // 37 // - ctx: context to use when instantiating the module and calling "run". 38 // - r: runtime to instantiate both the host and guest (compiled) module in. 39 // - compiled: guest binary compiled with `GOARCH=wasm GOOS=js` 40 // - config: the configuration such as args, env or filesystem to use. 41 // 42 // # Example 43 // 44 // After compiling your Wasm binary with wazero.Runtime's `CompileModule`, run 45 // it like below: 46 // 47 // // Use compilation cache to reduce performance penalty of multiple runs. 48 // ctx = experimental.WithCompilationCacheDirName(ctx, ".build") 49 // // Execute the "run" function, which corresponds to "main" in stars/main.go. 50 // err = gojs.Run(ctx, r, compiled, config) 51 // if exitErr, ok := err.(*sys.ExitError); ok && exitErr.ExitCode() != 0 { 52 // log.Panicln(err) 53 // } else if !ok { 54 // log.Panicln(err) 55 // } 56 // 57 // # Notes 58 // 59 // - Use wazero.RuntimeConfig `WithWasmCore2` to avoid needing to pick >1.0 60 // features set by `GOWASM` or used internally by Run. 61 // - Wasm generated by `GOARCH=wasm GOOS=js` is very slow to compile. 62 // Use experimental.WithCompilationCacheDirName to improve performance. 63 // - Both the host and guest module are closed after being run. 64 func Run(ctx context.Context, r wazero.Runtime, compiled wazero.CompiledModule, config wazero.ModuleConfig) error { 65 // Instantiate the imports needed by go-compiled wasm. 66 js, err := hostModuleBuilder(r).Instantiate(ctx, r) 67 if err != nil { 68 return err 69 } 70 defer js.Close(ctx) 71 72 // Instantiate the module compiled by go, noting it has no init function. 73 mod, err := r.InstantiateModule(ctx, compiled, config) 74 if err != nil { 75 return err 76 } 77 defer mod.Close(ctx) 78 79 // Extract the args and env from the module config and write it to memory. 80 ctx = WithState(ctx) 81 argc, argv, err := WriteArgsAndEnviron(ctx, mod) 82 if err != nil { 83 return err 84 } 85 // Invoke the run function. 86 _, err = mod.ExportedFunction("run").Call(ctx, uint64(argc), uint64(argv)) 87 return err 88 } 89 90 // hostModuleBuilder returns a new wazero.HostModuleBuilder 91 func hostModuleBuilder(r wazero.Runtime) (builder wazero.HostModuleBuilder) { 92 builder = r.NewHostModuleBuilder("go") 93 hfExporter := builder.(wasm.HostFuncExporter) 94 pfExporter := builder.(wasm.ProxyFuncExporter) 95 96 pfExporter.ExportProxyFunc(GetRandomData) 97 pfExporter.ExportProxyFunc(Nanotime1) 98 pfExporter.ExportProxyFunc(WasmExit) 99 pfExporter.ExportProxyFunc(CopyBytesToJS) 100 pfExporter.ExportProxyFunc(ValueCall) 101 pfExporter.ExportProxyFunc(ValueGet) 102 pfExporter.ExportProxyFunc(ValueIndex) 103 pfExporter.ExportProxyFunc(ValueLength) 104 pfExporter.ExportProxyFunc(ValueNew) 105 pfExporter.ExportProxyFunc(ValueSet) 106 pfExporter.ExportProxyFunc(WasmWrite) 107 hfExporter.ExportHostFunc(ResetMemoryDataView) 108 pfExporter.ExportProxyFunc(Walltime) 109 hfExporter.ExportHostFunc(ScheduleTimeoutEvent) 110 hfExporter.ExportHostFunc(ClearTimeoutEvent) 111 pfExporter.ExportProxyFunc(FinalizeRef) 112 pfExporter.ExportProxyFunc(StringVal) 113 hfExporter.ExportHostFunc(ValueDelete) 114 hfExporter.ExportHostFunc(ValueSetIndex) 115 hfExporter.ExportHostFunc(ValueInvoke) 116 pfExporter.ExportProxyFunc(ValuePrepareString) 117 hfExporter.ExportHostFunc(ValueInstanceOf) 118 pfExporter.ExportProxyFunc(ValueLoadString) 119 pfExporter.ExportProxyFunc(CopyBytesToGo) 120 hfExporter.ExportHostFunc(Debug) 121 return 122 }