github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/internal/task/task_asyncify_wasm.S (about) 1 .globaltype __stack_pointer, i32 2 3 .functype start_unwind (i32) -> () 4 .import_module start_unwind, asyncify 5 .import_name start_unwind, start_unwind 6 .functype stop_unwind () -> () 7 .import_module stop_unwind, asyncify 8 .import_name stop_unwind, stop_unwind 9 .functype start_rewind (i32) -> () 10 .import_module start_rewind, asyncify 11 .import_name start_rewind, start_rewind 12 .functype stop_rewind () -> () 13 .import_module stop_rewind, asyncify 14 .import_name stop_rewind, stop_rewind 15 16 .global tinygo_unwind 17 .hidden tinygo_unwind 18 .type tinygo_unwind,@function 19 tinygo_unwind: // func (state *stackState) unwind() 20 .functype tinygo_unwind (i32) -> () 21 // Check if we are rewinding. 22 i32.const 0 23 i32.load8_u tinygo_rewinding 24 if // if tinygo_rewinding { 25 // Stop rewinding. 26 call stop_rewind 27 i32.const 0 28 i32.const 0 29 i32.store8 tinygo_rewinding // tinygo_rewinding = false; 30 else 31 // Save the C stack pointer (destination structure pointer is in local 0). 32 local.get 0 33 global.get __stack_pointer 34 i32.store 4 // state.csp = getCurrentStackPointer() 35 // Ask asyncify to unwind. 36 // When resuming, asyncify will return this function with tinygo_rewinding set to true. 37 local.get 0 38 call start_unwind // asyncify.start_unwind(state) 39 end_if 40 return 41 end_function 42 43 .global tinygo_launch 44 .hidden tinygo_launch 45 .type tinygo_launch,@function 46 tinygo_launch: // func (state *state) launch() 47 .functype tinygo_launch (i32) -> () 48 // Switch to the goroutine's C stack. 49 global.get __stack_pointer // prev := getCurrentStackPointer() 50 local.get 0 51 i32.load 12 52 global.set __stack_pointer // setStackPointer(state.csp) 53 // Get the argument pack and entry pointer. 54 local.get 0 55 i32.load 4 // args := state.args 56 local.get 0 57 i32.load 0 // fn := state.entry 58 // Launch the entry function. 59 call_indirect (i32) -> () // fn(args) 60 // Stop unwinding. 61 call stop_unwind 62 // Restore the C stack. 63 global.set __stack_pointer // setStackPointer(prev) 64 return 65 end_function 66 67 .global tinygo_rewind 68 .hidden tinygo_rewind 69 .type tinygo_rewind,@function 70 tinygo_rewind: // func (state *state) rewind() 71 .functype tinygo_rewind (i32) -> () 72 // Switch to the goroutine's C stack. 73 global.get __stack_pointer // prev := getCurrentStackPointer() 74 local.get 0 75 i32.load 12 76 global.set __stack_pointer // setStackPointer(state.csp) 77 // Get the argument pack and entry pointer. 78 local.get 0 79 i32.load 4 // args := state.args 80 local.get 0 81 i32.load 0 // fn := state.entry 82 // Prepare to rewind. 83 i32.const 0 84 i32.const 1 85 i32.store8 tinygo_rewinding // tinygo_rewinding = true; 86 local.get 0 87 i32.const 8 88 i32.add 89 call start_rewind // asyncify.start_rewind(&state.stackState) 90 // Launch the entry function. 91 // This will actually rewind the call stack. 92 call_indirect (i32) -> () // fn(args) 93 // Stop unwinding. 94 call stop_unwind 95 // Restore the C stack. 96 global.set __stack_pointer // setStackPointer(prev) 97 return 98 end_function 99 100 .hidden tinygo_rewinding # @tinygo_rewinding 101 .type tinygo_rewinding,@object 102 .section .bss.tinygo_rewinding,"",@ 103 .globl tinygo_rewinding 104 tinygo_rewinding: 105 .int8 0 # 0x0 106 .size tinygo_rewinding, 1