mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
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>
This commit is contained in:
parent
5fdacfa89f
commit
e083dc6307
18 changed files with 482 additions and 49 deletions
|
|
@ -25,6 +25,7 @@ var Register = map[string]int16{
|
|||
"RET1": REG_RET1,
|
||||
"RET2": REG_RET2,
|
||||
"RET3": REG_RET3,
|
||||
"RUN": REG_RUN,
|
||||
|
||||
"R0": REG_R0,
|
||||
"R1": REG_R1,
|
||||
|
|
@ -487,7 +488,7 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
|
|||
p = appendp(p, AEnd) // end of Loop
|
||||
}
|
||||
|
||||
case obj.ARET:
|
||||
case obj.ARET, ARETUNWIND:
|
||||
ret := *p
|
||||
p.As = obj.ANOP
|
||||
|
||||
|
|
@ -528,7 +529,14 @@ func preprocess(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
|
|||
p = appendp(p, AI32Add)
|
||||
p = appendp(p, ASet, regAddr(REG_SP))
|
||||
|
||||
// not switching goroutine, return 0
|
||||
if ret.As == ARETUNWIND {
|
||||
// function needs to unwind the WebAssembly stack, return 1
|
||||
p = appendp(p, AI32Const, constAddr(1))
|
||||
p = appendp(p, AReturn)
|
||||
break
|
||||
}
|
||||
|
||||
// not unwinding the WebAssembly stack, return 0
|
||||
p = appendp(p, AI32Const, constAddr(0))
|
||||
p = appendp(p, AReturn)
|
||||
}
|
||||
|
|
@ -726,7 +734,7 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
|
|||
}
|
||||
reg := p.From.Reg
|
||||
switch {
|
||||
case reg >= REG_PC_F && reg <= REG_RET3:
|
||||
case reg >= REG_PC_F && reg <= REG_RUN:
|
||||
w.WriteByte(0x23) // get_global
|
||||
writeUleb128(w, uint64(reg-REG_PC_F))
|
||||
case reg >= REG_R0 && reg <= REG_F15:
|
||||
|
|
@ -743,7 +751,7 @@ func assemble(ctxt *obj.Link, s *obj.LSym, newprog obj.ProgAlloc) {
|
|||
}
|
||||
reg := p.To.Reg
|
||||
switch {
|
||||
case reg >= REG_PC_F && reg <= REG_RET3:
|
||||
case reg >= REG_PC_F && reg <= REG_RUN:
|
||||
w.WriteByte(0x24) // set_global
|
||||
writeUleb128(w, uint64(reg-REG_PC_F))
|
||||
case reg >= REG_R0 && reg <= REG_F15:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue