From 0b55e05d06bc760070b8ca9f99c01c3d8e67e7db Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Wed, 10 Oct 2012 18:56:16 +0200 Subject: [PATCH] FFI: Compile ffi.gc(). --- src/lib_ffi.c | 2 +- src/lj_crecord.c | 43 +++++++++++++++++++++++++++---------------- src/lj_crecord.h | 1 + 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 689f7a9d..37e66245 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -762,7 +762,7 @@ LJLIB_CF(ffi_metatype) LJLIB_PUSH(top-7) LJLIB_SET(!) /* Store reference to finalizer table. */ -LJLIB_CF(ffi_gc) +LJLIB_CF(ffi_gc) LJLIB_REC(.) { GCcdata *cd = ffi_checkcdata(L, 1); TValue *fin = lj_lib_checkany(L, 2); diff --git a/src/lj_crecord.c b/src/lj_crecord.c index f9220322..9d361a7a 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -862,6 +862,25 @@ again: } } +/* Record setting a finalizer. */ +static void crec_finalizer(jit_State *J, TRef trcd, cTValue *fin) +{ + TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd); + TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4)); + if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; } + if (tvisfunc(fin)) { + emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin))); + emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC)); + } else if (tviscdata(fin)) { + emitir(IRT(IR_XSTORE, IRT_P32), trlo, + lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA)); + emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA)); + } else { + lj_trace_err(J, LJ_TRERR_BADTYPE); + } + J->needsnap = 1; +} + /* Record cdata allocation. */ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) { @@ -955,22 +974,8 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) } /* Handle __gc metamethod. */ fin = lj_ctype_meta(cts, id, MM_gc); - if (fin) { - TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd); - TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4)); - if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; } - if (tvisfunc(fin)) { - emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin))); - emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC)); - } else if (tviscdata(fin)) { - emitir(IRT(IR_XSTORE, IRT_P32), trlo, - lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA)); - emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA)); - } else { - lj_trace_err(J, LJ_TRERR_BADTYPE); - } - J->needsnap = 1; - } + if (fin) + crec_finalizer(J, trcd, fin); } } @@ -1611,6 +1616,12 @@ void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd) J->base[0] = J->base[1] = J->base[2] = TREF_NIL; } +void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) +{ + argv2cdata(J, J->base[0], &rd->argv[0]); + crec_finalizer(J, J->base[0], &rd->argv[1]); +} + /* -- Miscellaneous library functions ------------------------------------- */ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) diff --git a/src/lj_crecord.h b/src/lj_crecord.h index bd217651..c222d41e 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h @@ -24,6 +24,7 @@ LJ_FUNC void LJ_FASTCALL recff_ffi_typeof(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_istype(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_abi(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd); +LJ_FUNC void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd); LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); #endif