diff options
author | Richard Musiol <mail@richard-musiol.de> | 2018-05-20 00:56:36 +0200 |
---|---|---|
committer | Austin Clements <austin@google.com> | 2018-06-14 21:50:53 +0000 |
commit | e083dc6307b6593bdd44b219ffd21699d6f17fd7 (patch) | |
tree | 2a411d82639a778c6aa107529b1d708034c7a7f1 /src/runtime/rt0_js_wasm.s | |
parent | 5fdacfa89f871888d6f8fde726b8f95f11e674d6 (diff) | |
download | go-e083dc6307b6593bdd44b219ffd21699d6f17fd7.tar.gz go-e083dc6307b6593bdd44b219ffd21699d6f17fd7.zip |
runtime, sycall/js: add support for callbacks from JavaScript
This commit adds support for JavaScript callbacks back into
WebAssembly. This is experimental API, just like the rest of the
syscall/js package. The time package now also uses this mechanism
to properly support timers without resorting to a busy loop.
JavaScript code can call into the same entry point multiple times.
The new RUN register is used to keep track of the program's
run state. Possible values are: starting, running, paused and exited.
If no goroutine is ready any more, the scheduler can put the
program into the "paused" state and the WebAssembly code will
stop running. When a callback occurs, the JavaScript code puts
the callback data into a queue and then calls into WebAssembly
to allow the Go code to continue running.
Updates #18892
Updates #25506
Change-Id: Ib8701cfa0536d10d69bd541c85b0e2a754eb54fb
Reviewed-on: https://go-review.googlesource.com/114197
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/runtime/rt0_js_wasm.s')
-rw-r--r-- | src/runtime/rt0_js_wasm.s | 78 |
1 files changed, 57 insertions, 21 deletions
diff --git a/src/runtime/rt0_js_wasm.s b/src/runtime/rt0_js_wasm.s index 2a878d990c..e20f623610 100644 --- a/src/runtime/rt0_js_wasm.s +++ b/src/runtime/rt0_js_wasm.s @@ -5,45 +5,81 @@ #include "go_asm.h" #include "textflag.h" +// The register RUN indicates the current run state of the program. +// Possible values are: +#define RUN_STARTING 0 +#define RUN_RUNNING 1 +#define RUN_PAUSED 2 +#define RUN_EXITED 3 + // _rt0_wasm_js does NOT follow the Go ABI. It has two WebAssembly parameters: // R0: argc (i32) // R1: argv (i32) TEXT _rt0_wasm_js(SB),NOSPLIT,$0 - MOVD $runtime·wasmStack+m0Stack__size(SB), SP + Get RUN + I32Const $RUN_STARTING + I32Eq + If + MOVD $runtime·wasmStack+m0Stack__size(SB), SP + + Get SP + Get R0 // argc + I64ExtendUI32 + I64Store $0 - Get SP - Get R0 // argc - I64ExtendUI32 - I64Store $0 + Get SP + Get R1 // argv + I64ExtendUI32 + I64Store $8 - Get SP - Get R1 // argv - I64ExtendUI32 - I64Store $8 + I32Const $runtime·rt0_go(SB) + I32Const $16 + I32ShrU + Set PC_F - I32Const $runtime·rt0_go(SB) - I32Const $16 - I32ShrU - Set PC_F + I32Const $RUN_RUNNING + Set RUN + Else + Get RUN + I32Const $RUN_PAUSED + I32Eq + If + I32Const $RUN_RUNNING + Set RUN + Else + Unreachable + End + End -// Call the function for the current PC_F. Repeat until SP=0 indicates program end. +// Call the function for the current PC_F. Repeat until RUN != 0 indicates pause or exit. // The WebAssembly stack may unwind, e.g. when switching goroutines. // The Go stack on the linear memory is then used to jump to the correct functions // with this loop, without having to restore the full WebAssembly stack. loop: Loop - Get SP - I32Eqz - If - Return - End - Get PC_F CallIndirect $0 Drop - Br loop + Get RUN + I32Const $RUN_RUNNING + I32Eq + BrIf loop End + Return + +TEXT runtime·pause(SB), NOSPLIT, $0 + I32Const $RUN_PAUSED + Set RUN + RETUNWIND + +TEXT runtime·exit(SB), NOSPLIT, $0-8 + Call runtime·wasmExit(SB) + Drop + I32Const $RUN_EXITED + Set RUN + RETUNWIND + TEXT _rt0_wasm_js_lib(SB),NOSPLIT,$0 UNDEF |