From 51290e5842252fee3a0ebf5d6ebe12a0118e3c4c Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 17 Nov 2021 17:06:05 +0100 Subject: [PATCH] wasm: support -scheduler=none Previously, -scheduler=none wasn't possible for WASM targets: $ tinygo run -target=wasm -scheduler=none ./testdata/stdlib.go src/runtime/runtime_wasm_js.go:34:2: attempted to start a goroutine without a scheduler With this commit, it works just fine: $ tinygo run -target=wasm -scheduler=none ./testdata/stdlib.go stdin: /dev/stdin stdout: /dev/stdout stderr: /dev/stderr pseudorandom number: 1298498081 strings.IndexByte: 2 strings.Replace: An-example-string Supporting `-scheduler=none` has some benefits: * it reduces file size a lot compared to having a scheduler * it allows JavaScript to call exported functions --- main_test.go | 2 +- src/runtime/runtime_wasm_js.go | 28 --------------------- src/runtime/runtime_wasm_js_scheduler.go | 32 ++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 29 deletions(-) create mode 100644 src/runtime/runtime_wasm_js_scheduler.go diff --git a/main_test.go b/main_test.go index f4f973f1..d1ef1964 100644 --- a/main_test.go +++ b/main_test.go @@ -164,7 +164,7 @@ func runPlatTests(options compileopts.Options, tests []string, t *testing.T) { t.Parallel() runTest("env.go", options, t, []string{"first", "second"}, []string{"ENV1=VALUE1", "ENV2=VALUE2"}) }) - if options.Target == "wasi" { + if options.Target == "wasi" || options.Target == "wasm" { t.Run("alias.go-scheduler-none", func(t *testing.T) { t.Parallel() options := compileopts.Options(options) diff --git a/src/runtime/runtime_wasm_js.go b/src/runtime/runtime_wasm_js.go index a5f2505d..60d8760d 100644 --- a/src/runtime/runtime_wasm_js.go +++ b/src/runtime/runtime_wasm_js.go @@ -29,34 +29,6 @@ func setEventHandler(fn func()) { handleEvent = fn } -//export resume -func resume() { - go func() { - handleEvent() - }() - - if wasmNested { - minSched() - return - } - - wasmNested = true - scheduler() - wasmNested = false -} - -//export go_scheduler -func go_scheduler() { - if wasmNested { - minSched() - return - } - - wasmNested = true - scheduler() - wasmNested = false -} - func ticksToNanoseconds(ticks timeUnit) int64 { // The JavaScript API works in float64 milliseconds, so convert to // nanoseconds first before converting to a timeUnit (which is a float64), diff --git a/src/runtime/runtime_wasm_js_scheduler.go b/src/runtime/runtime_wasm_js_scheduler.go new file mode 100644 index 00000000..ab80cf1d --- /dev/null +++ b/src/runtime/runtime_wasm_js_scheduler.go @@ -0,0 +1,32 @@ +//go:build wasm && !wasi && !scheduler.none +// +build wasm,!wasi,!scheduler.none + +package runtime + +//export resume +func resume() { + go func() { + handleEvent() + }() + + if wasmNested { + minSched() + return + } + + wasmNested = true + scheduler() + wasmNested = false +} + +//export go_scheduler +func go_scheduler() { + if wasmNested { + minSched() + return + } + + wasmNested = true + scheduler() + wasmNested = false +}