mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 15:34:09 +00:00
Implement coroutines.
TODO: delete LREG, caused problems while implementing this (x64 doesn't have LREG).
This commit is contained in:
parent
60fb35cb68
commit
d90293f55e
@ -512,6 +512,7 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
| st RD, SAVE_NRES
|
| st RD, SAVE_NRES
|
||||||
| stg RD, SAVE_ERRF
|
| stg RD, SAVE_ERRF
|
||||||
| stg KBASE, L:RB->cframe
|
| stg KBASE, L:RB->cframe
|
||||||
|
| lgr LREG, L:RB
|
||||||
| clm RD, 1, L:RB->status
|
| clm RD, 1, L:RB->status
|
||||||
| je >2 // Initial resume (like a call).
|
| je >2 // Initial resume (like a call).
|
||||||
|
|
|
|
||||||
@ -1386,19 +1387,169 @@ static void build_subroutines(BuildCtx *ctx)
|
|||||||
|.macro coroutine_resume_wrap, resume
|
|.macro coroutine_resume_wrap, resume
|
||||||
|.if resume
|
|.if resume
|
||||||
|.ffunc_1 coroutine_resume
|
|.ffunc_1 coroutine_resume
|
||||||
|
| lg L:RB, 0(BASE)
|
||||||
|
| lgr L:TMPR2, L:RB // Save type for checktptp.
|
||||||
|
| cleartp L:RB
|
||||||
|.else
|
|.else
|
||||||
|.ffunc coroutine_wrap_aux
|
|.ffunc coroutine_wrap_aux
|
||||||
|
| lg CFUNC:RB, -16(BASE)
|
||||||
|
| cleartp CFUNC:RB
|
||||||
|
| lg L:RB, CFUNC:RB->upvalue[0].gcr
|
||||||
|
| cleartp L:RB
|
||||||
|.endif
|
|.endif
|
||||||
| stg r0, 0(r0)
|
| lg PC, -8(BASE)
|
||||||
| stg r0, 0(r0)
|
| stg PC, SAVE_PC
|
||||||
|
| stg L:RB, TMP_STACK
|
||||||
|
|.if resume
|
||||||
|
| checktptp L:TMPR2, LJ_TTHREAD, ->fff_fallback
|
||||||
|
|.endif
|
||||||
|
| ltg TMPR2, L:RB->cframe; jne ->fff_fallback
|
||||||
|
| // TODO: replace with cli.
|
||||||
|
| llgc TMPR1, L:RB->status
|
||||||
|
| cghi TMPR1, (uint8_t)LUA_YIELD; jh ->fff_fallback
|
||||||
|
| lg RA, L:RB->top
|
||||||
|
| je >1 // Status != LUA_YIELD (i.e. 0)?
|
||||||
|
| cg RA, L:RB->base // Check for presence of initial func.
|
||||||
|
| je ->fff_fallback
|
||||||
|
| lg PC, -8(RA) // Move initial function up.
|
||||||
|
| stg PC, 0(RA)
|
||||||
|
| la RA, 8(RA)
|
||||||
|
|1:
|
||||||
|
| sllg TMPR1, NARGS:RD, 3(r0)
|
||||||
|
|.if resume
|
||||||
|
| lay PC, -16(TMPR1, RA) // Check stack space (-1-thread).
|
||||||
|
|.else
|
||||||
|
| lay PC, -8(TMPR1, RA) // Check stack space (-1).
|
||||||
|
|.endif
|
||||||
|
| clg PC, L:RB->maxstack; jh ->fff_fallback
|
||||||
|
| stg PC, L:RB->top
|
||||||
|
|
|
||||||
|
| lg L:RB, SAVE_L
|
||||||
|
| stg BASE, L:RB->base
|
||||||
|
|.if resume
|
||||||
|
| la BASE, 8(BASE) // Keep resumed thread in stack for GC.
|
||||||
|
|.endif
|
||||||
|
| stg BASE, L:RB->top
|
||||||
|
|.if resume
|
||||||
|
| lay RB, -24(TMPR1, BASE) // RB = end of source for stack move.
|
||||||
|
|.else
|
||||||
|
| lay RB, -16(TMPR1, BASE) // RB = end of source for stack move.
|
||||||
|
|.endif
|
||||||
|
| sgr RB, PC // Relative to PC.
|
||||||
|
|
|
||||||
|
| cgr PC, RA
|
||||||
|
| je >3
|
||||||
|
|2: // Move args to coroutine.
|
||||||
|
| lg RC, 0(RB, PC)
|
||||||
|
| stg RC, -8(PC)
|
||||||
|
| // TODO: replace with branch on count/index?
|
||||||
|
| lay PC, -8(PC)
|
||||||
|
| cgr PC, RA
|
||||||
|
| jne <2
|
||||||
|
|3:
|
||||||
|
| lgr CARG2, RA
|
||||||
|
| lg L:CARG1, TMP_STACK
|
||||||
|
| lghi CARG3, 0
|
||||||
|
| lghi CARG4, 0
|
||||||
|
| brasl r14, ->vm_resume // (lua_State *L, TValue *base, 0, 0)
|
||||||
|
|
|
||||||
|
| lg L:RB, SAVE_L
|
||||||
|
| lg L:PC, TMP_STACK
|
||||||
|
| lg BASE, L:RB->base
|
||||||
|
| stg L:RB, (DISPATCH_GL(cur_L))(DISPATCH)
|
||||||
|
| set_vmstate INTERP
|
||||||
|
|
|
||||||
|
| clfi CRET1, LUA_YIELD
|
||||||
|
| jh >8
|
||||||
|
|4:
|
||||||
|
| lg RA, L:PC->base
|
||||||
|
| lg KBASE, L:PC->top
|
||||||
|
| stg RA, L:PC->top // Clear coroutine stack.
|
||||||
|
| lgr PC, KBASE
|
||||||
|
| sgr PC, RA
|
||||||
|
| je >6 // No results?
|
||||||
|
| la RD, 0(PC, BASE)
|
||||||
|
| llgfr PC, PC
|
||||||
|
| srlg PC, PC, 3(r0)
|
||||||
|
| clg RD, L:RB->maxstack
|
||||||
|
| jh >9 // Need to grow stack?
|
||||||
|
|
|
||||||
|
| lgr RB, BASE
|
||||||
|
| sgr RB, RA
|
||||||
|
|5: // Move results from coroutine.
|
||||||
|
| lg RD, 0(RA)
|
||||||
|
| stg RD, 0(RA, RB)
|
||||||
|
| // TODO: branch on count/index?
|
||||||
|
| la RA, 8(RA)
|
||||||
|
| cgr RA, KBASE
|
||||||
|
| jne <5
|
||||||
|
|6:
|
||||||
|
|.if resume
|
||||||
|
| la RD, 2(PC) // nresults+1 = 1 + true + results.
|
||||||
|
| load_true ITYPE // Prepend true to results.
|
||||||
|
| stg ITYPE, -8(BASE)
|
||||||
|
|.else
|
||||||
|
| la RD, 1(PC) // nresults+1 = 1 + results.
|
||||||
|
|.endif
|
||||||
|
|7:
|
||||||
|
| lg PC, SAVE_PC
|
||||||
|
| st RD, SAVE_MULTRES
|
||||||
|
|.if resume
|
||||||
|
| lghi RA, -8
|
||||||
|
|.else
|
||||||
|
| lghi RA, 0
|
||||||
|
|.endif
|
||||||
|
| tmll PC, FRAME_TYPE
|
||||||
|
| je ->BC_RET_Z
|
||||||
|
| j ->vm_return
|
||||||
|
|
|
||||||
|
|8: // Coroutine returned with error (at co->top-1).
|
||||||
|
|.if resume
|
||||||
|
| load_false ITYPE // Prepend false to results.
|
||||||
|
| stg ITYPE, -8(BASE)
|
||||||
|
| lg RA, L:PC->top
|
||||||
|
| aghi RA, -8
|
||||||
|
| stg RA, L:PC->top // Clear error from coroutine stack.
|
||||||
|
| // Copy error message.
|
||||||
|
| lg RD, 0(RA)
|
||||||
|
| stg RD, 0(BASE)
|
||||||
|
| lghi RD, 1+2 // nresults+1 = 1 + false + error.
|
||||||
|
| j <7
|
||||||
|
|.else
|
||||||
|
| lgr CARG2, L:PC
|
||||||
|
| lgr CARG1, L:RB
|
||||||
|
| brasl r14, extern lj_ffh_coroutine_wrap_err // (lua_State *L, lua_State *co)
|
||||||
|
| // Error function does not return.
|
||||||
|
|.endif
|
||||||
|
|
|
||||||
|
|9: // Handle stack expansion on return from yield.
|
||||||
|
| lg L:RA, TMP_STACK
|
||||||
|
| stg KBASE, L:RA->top // Undo coroutine stack clearing.
|
||||||
|
| lgr CARG2, PC
|
||||||
|
| lgr CARG1, L:RB
|
||||||
|
| brasl r14, extern lj_state_growstack // (lua_State *L, int n)
|
||||||
|
| lg L:PC, TMP_STACK
|
||||||
|
| lg BASE, L:RB->base
|
||||||
|
| j <4 // Retry the stack move.
|
||||||
|.endmacro
|
|.endmacro
|
||||||
|
|
|
|
||||||
| coroutine_resume_wrap 1 // coroutine.resume
|
| coroutine_resume_wrap 1 // coroutine.resume
|
||||||
| coroutine_resume_wrap 0 // coroutine.wrap
|
| coroutine_resume_wrap 0 // coroutine.wrap
|
||||||
|
|
|
|
||||||
|.ffunc coroutine_yield
|
|.ffunc coroutine_yield
|
||||||
| stg r0, 0(r0)
|
| lg L:RB, SAVE_L
|
||||||
| stg r0, 0(r0)
|
| lg TMPR2, L:RB->cframe
|
||||||
|
| tmll TMPR2, CFRAME_RESUME
|
||||||
|
| je ->fff_fallback
|
||||||
|
| stg BASE, L:RB->base
|
||||||
|
| sllg TMPR1, NARGS:RD, 3(r0)
|
||||||
|
| lay RD, -8(TMPR1, BASE)
|
||||||
|
| stg RD, L:RB->top
|
||||||
|
| lghi RD, 0
|
||||||
|
| stg RD, L:RB->cframe
|
||||||
|
| lhi RA, LUA_YIELD
|
||||||
|
| stc RA, L:RB->status
|
||||||
|
| j ->vm_leave_unw
|
||||||
|
|
|
|
||||||
|//-- Math library -------------------------------------------------------
|
|//-- Math library -------------------------------------------------------
|
||||||
|
|
|
|
||||||
@ -3906,7 +4057,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
|
|||||||
| lay RD, -8(RD,BASE)
|
| lay RD, -8(RD,BASE)
|
||||||
| stg BASE, L:RB->base
|
| stg BASE, L:RB->base
|
||||||
| lay RA, (8*LUA_MINSTACK)(RD)
|
| lay RA, (8*LUA_MINSTACK)(RD)
|
||||||
| cg RA, L:RB->maxstack
|
| clg RA, L:RB->maxstack
|
||||||
| stg RD, L:RB->top
|
| stg RD, L:RB->top
|
||||||
| lgr CARG1, L:RB // Caveat: CARG1 may be RA.
|
| lgr CARG1, L:RB // Caveat: CARG1 may be RA.
|
||||||
if (op != BC_FUNCC) {
|
if (op != BC_FUNCC) {
|
||||||
|
Loading…
Reference in New Issue
Block a user