FFI: Add callback support for ARM.
This commit is contained in:
@@ -502,22 +502,30 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
| ldr CARG1, [BASE, #-16] // Get continuation.
|
||||
| mov CARG4, BASE
|
||||
| mov BASE, RB // Restore caller BASE.
|
||||
| cmp CARG1, #0
|
||||
#if LJ_HASFFI
|
||||
| cmp CARG1, #1
|
||||
#endif
|
||||
| ldr PC, [CARG4, #-12] // Restore PC from [cont|PC].
|
||||
| beq >1
|
||||
| ldr CARG3, LFUNC:CARG3->field_pc
|
||||
| mvn INS, #~LJ_TNIL
|
||||
| add CARG2, RA, RC
|
||||
| str INS, [CARG2, #-4] // Ensure one valid arg.
|
||||
#if LJ_HASFFI
|
||||
| bls >1
|
||||
#endif
|
||||
| ldr KBASE, [CARG3, #PC2PROTO(k)]
|
||||
| // BASE = base, RA = resultptr, CARG4 = meta base
|
||||
| bx CARG1
|
||||
| bx CARG1
|
||||
|
|
||||
|1: // Tail call from C function.
|
||||
#if LJ_HASFFI
|
||||
|1:
|
||||
| beq ->cont_ffi_callback // cont = 1: return from FFI callback.
|
||||
| // cont = 0: tailcall from C function.
|
||||
| ldr CARG3, [BASE, FRAME_FUNC]
|
||||
| sub CARG4, CARG4, #16
|
||||
| sub RC, CARG4, BASE
|
||||
| b ->vm_call_tail
|
||||
#endif
|
||||
|
|
||||
|->cont_cat: // RA = resultptr, CARG4 = meta base
|
||||
| ldr INS, [PC, #-4]
|
||||
@@ -2177,6 +2185,50 @@ static void build_subroutines(BuildCtx *ctx)
|
||||
|//-----------------------------------------------------------------------
|
||||
|//-- FFI helper functions -----------------------------------------------
|
||||
|//-----------------------------------------------------------------------
|
||||
|
|
||||
|// Handler for callback functions.
|
||||
|// Saveregs already performed. Callback slot number in [sp], g in r12.
|
||||
|->vm_ffi_callback:
|
||||
#if LJ_HASFFI
|
||||
|.type CTSTATE, CTState, PC
|
||||
| ldr CTSTATE, GL:r12->ctype_state
|
||||
| add DISPATCH, r12, #GG_G2DISP
|
||||
| strd CARG12, CTSTATE->cb.gpr[0]
|
||||
| strd CARG34, CTSTATE->cb.gpr[2]
|
||||
| ldr CARG4, [sp]
|
||||
| add CARG3, sp, #CFRAME_SIZE
|
||||
| mov CARG1, CTSTATE
|
||||
| lsr CARG4, CARG4, #3
|
||||
| str CARG3, CTSTATE->cb.stack
|
||||
| mov CARG2, sp
|
||||
| str CARG4, CTSTATE->cb.slot
|
||||
| str CTSTATE, SAVE_PC // Any value outside of bytecode is ok.
|
||||
| bl extern lj_ccallback_enter // (CTState *cts, void *cf)
|
||||
| // Returns lua_State *.
|
||||
| ldr BASE, L:CRET1->base
|
||||
| mv_vmstate CARG2, INTERP
|
||||
| ldr RC, L:CRET1->top
|
||||
| mov MASKR8, #255
|
||||
| ldr LFUNC:CARG3, [BASE, FRAME_FUNC]
|
||||
| mov L, CRET1
|
||||
| sub RC, RC, BASE
|
||||
| lsl MASKR8, MASKR8, #3 // MASKR8 = 255*8.
|
||||
| st_vmstate CARG2
|
||||
| ins_callt
|
||||
#endif
|
||||
|
|
||||
|->cont_ffi_callback: // Return from FFI callback.
|
||||
#if LJ_HASFFI
|
||||
| ldr CTSTATE, [DISPATCH, #DISPATCH_GL(ctype_state)]
|
||||
| str BASE, L->base
|
||||
| str CARG4, L->top
|
||||
| str L, CTSTATE->L
|
||||
| mov CARG1, CTSTATE
|
||||
| mov CARG2, RA
|
||||
| bl extern lj_ccallback_leave // (CTState *cts, TValue *o)
|
||||
| ldrd CARG12, CTSTATE->cb.gpr[0]
|
||||
| b ->vm_leave_unw
|
||||
#endif
|
||||
|
|
||||
|->vm_ffi_call: // Call C function via FFI.
|
||||
| // Caveat: needs special frame unwinding, see below.
|
||||
|
||||
Reference in New Issue
Block a user