FFI: Add callback support for ARM.

This commit is contained in:
Mike Pall
2011-12-12 23:12:25 +01:00
parent 1b0d646004
commit 03c51fc578
5 changed files with 1328 additions and 1147 deletions

View File

@@ -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.