diff options
author | Mike Pall <mike> | 2013-05-24 17:44:55 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2013-05-24 17:44:55 +0200 |
commit | 992f7d4b71d0f39266c9b2d7f8ce28c278afb667 (patch) | |
tree | f12f1ec3a7df3dee5035b499a98292a2f78aa8f1 | |
parent | 4c1f9dd0f7fdbf79ed62588c64417d6238fd5c51 (diff) | |
download | luajit-992f7d4b71d0f39266c9b2d7f8ce28c278afb667.tar.gz luajit-992f7d4b71d0f39266c9b2d7f8ce28c278afb667.tar.bz2 luajit-992f7d4b71d0f39266c9b2d7f8ce28c278afb667.zip |
FFI: Refactor ffi.gc()/__gc. Compile ffi.gc(cdata, nil), too.
-rw-r--r-- | src/lib_ffi.c | 10 | ||||
-rw-r--r-- | src/lj_cdata.c | 15 | ||||
-rw-r--r-- | src/lj_cdata.h | 3 | ||||
-rw-r--r-- | src/lj_crecord.c | 24 | ||||
-rw-r--r-- | src/lj_ircall.h | 2 |
5 files changed, 22 insertions, 32 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 562255aa..3310b205 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -768,19 +768,11 @@ LJLIB_CF(ffi_gc) LJLIB_REC(.) | |||
768 | GCcdata *cd = ffi_checkcdata(L, 1); | 768 | GCcdata *cd = ffi_checkcdata(L, 1); |
769 | TValue *fin = lj_lib_checkany(L, 2); | 769 | TValue *fin = lj_lib_checkany(L, 2); |
770 | CTState *cts = ctype_cts(L); | 770 | CTState *cts = ctype_cts(L); |
771 | GCtab *t = cts->finalizer; | ||
772 | CType *ct = ctype_raw(cts, cd->ctypeid); | 771 | CType *ct = ctype_raw(cts, cd->ctypeid); |
773 | if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) || | 772 | if (!(ctype_isptr(ct->info) || ctype_isstruct(ct->info) || |
774 | ctype_isrefarray(ct->info))) | 773 | ctype_isrefarray(ct->info))) |
775 | lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE); | 774 | lj_err_arg(L, 1, LJ_ERR_FFI_INVTYPE); |
776 | if (gcref(t->metatable)) { /* Update finalizer table, if still enabled. */ | 775 | lj_cdata_setfin(L, cd, gcval(fin), itype(fin)); |
777 | copyTV(L, lj_tab_set(L, t, L->base), fin); | ||
778 | lj_gc_anybarriert(L, t); | ||
779 | if (!tvisnil(fin)) | ||
780 | cd->marked |= LJ_GC_CDATA_FIN; | ||
781 | else | ||
782 | cd->marked &= ~LJ_GC_CDATA_FIN; | ||
783 | } | ||
784 | L->top = L->base+1; /* Pass through the cdata object. */ | 776 | L->top = L->base+1; /* Pass through the cdata object. */ |
785 | return 1; | 777 | return 1; |
786 | } | 778 | } |
diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 80dcf4e5..aa3bd1a5 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c | |||
@@ -75,21 +75,20 @@ void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd) | |||
75 | } | 75 | } |
76 | } | 76 | } |
77 | 77 | ||
78 | TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd) | 78 | void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj, uint32_t it) |
79 | { | 79 | { |
80 | global_State *g = G(L); | 80 | GCtab *t = ctype_ctsG(G(L))->finalizer; |
81 | GCtab *t = ctype_ctsG(g)->finalizer; | ||
82 | if (gcref(t->metatable)) { | 81 | if (gcref(t->metatable)) { |
83 | /* Add cdata to finalizer table, if still enabled. */ | 82 | /* Add cdata to finalizer table, if still enabled. */ |
84 | TValue *tv, tmp; | 83 | TValue *tv, tmp; |
85 | setcdataV(L, &tmp, cd); | 84 | setcdataV(L, &tmp, cd); |
86 | lj_gc_anybarriert(L, t); | 85 | lj_gc_anybarriert(L, t); |
87 | tv = lj_tab_set(L, t, &tmp); | 86 | tv = lj_tab_set(L, t, &tmp); |
88 | cd->marked |= LJ_GC_CDATA_FIN; | 87 | setgcV(L, tv, obj, it); |
89 | return tv; | 88 | if (!tvisnil(tv)) |
90 | } else { | 89 | cd->marked |= LJ_GC_CDATA_FIN; |
91 | /* Otherwise return dummy TValue. */ | 90 | else |
92 | return &g->tmptv; | 91 | cd->marked &= ~LJ_GC_CDATA_FIN; |
93 | } | 92 | } |
94 | } | 93 | } |
95 | 94 | ||
diff --git a/src/lj_cdata.h b/src/lj_cdata.h index f0c23ac4..7db1ca1e 100644 --- a/src/lj_cdata.h +++ b/src/lj_cdata.h | |||
@@ -62,7 +62,8 @@ LJ_FUNC GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz, | |||
62 | CTSize align); | 62 | CTSize align); |
63 | 63 | ||
64 | LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd); | 64 | LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd); |
65 | LJ_FUNCA TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd); | 65 | LJ_FUNC void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj, |
66 | uint32_t it); | ||
66 | 67 | ||
67 | LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, | 68 | LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, |
68 | uint8_t **pp, CTInfo *qual); | 69 | uint8_t **pp, CTInfo *qual); |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index ef6e5f82..c3b01f63 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -863,21 +863,17 @@ again: | |||
863 | } | 863 | } |
864 | 864 | ||
865 | /* Record setting a finalizer. */ | 865 | /* Record setting a finalizer. */ |
866 | static void crec_finalizer(jit_State *J, TRef trcd, cTValue *fin) | 866 | static void crec_finalizer(jit_State *J, TRef trcd, TRef trfin, cTValue *fin) |
867 | { | 867 | { |
868 | TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd); | 868 | if (tvisgcv(fin)) { |
869 | TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4)); | 869 | if (!trfin) trfin = lj_ir_kptr(J, gcval(fin)); |
870 | if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; } | 870 | } else if (tvisnil(fin)) { |
871 | if (tvisfunc(fin)) { | 871 | trfin = lj_ir_kptr(J, NULL); |
872 | emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin))); | ||
873 | emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC)); | ||
874 | } else if (tviscdata(fin)) { | ||
875 | emitir(IRT(IR_XSTORE, IRT_P32), trlo, | ||
876 | lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA)); | ||
877 | emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA)); | ||
878 | } else { | 872 | } else { |
879 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 873 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
880 | } | 874 | } |
875 | lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd, | ||
876 | trfin, lj_ir_kint(J, (int32_t)itype(fin))); | ||
881 | J->needsnap = 1; | 877 | J->needsnap = 1; |
882 | } | 878 | } |
883 | 879 | ||
@@ -1001,7 +997,7 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id) | |||
1001 | /* Handle __gc metamethod. */ | 997 | /* Handle __gc metamethod. */ |
1002 | fin = lj_ctype_meta(cts, id, MM_gc); | 998 | fin = lj_ctype_meta(cts, id, MM_gc); |
1003 | if (fin) | 999 | if (fin) |
1004 | crec_finalizer(J, trcd, fin); | 1000 | crec_finalizer(J, trcd, 0, fin); |
1005 | } | 1001 | } |
1006 | 1002 | ||
1007 | /* Record argument conversions. */ | 1003 | /* Record argument conversions. */ |
@@ -1648,7 +1644,9 @@ void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd) | |||
1648 | void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) | 1644 | void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) |
1649 | { | 1645 | { |
1650 | argv2cdata(J, J->base[0], &rd->argv[0]); | 1646 | argv2cdata(J, J->base[0], &rd->argv[0]); |
1651 | crec_finalizer(J, J->base[0], &rd->argv[1]); | 1647 | if (!J->base[1]) |
1648 | lj_trace_err(J, LJ_TRERR_BADTYPE); | ||
1649 | crec_finalizer(J, J->base[0], J->base[1], &rd->argv[1]); | ||
1652 | } | 1650 | } |
1653 | 1651 | ||
1654 | /* -- 64 bit bit.* library functions -------------------------------------- */ | 1652 | /* -- 64 bit bit.* library functions -------------------------------------- */ |
diff --git a/src/lj_ircall.h b/src/lj_ircall.h index bdcfea0b..9e1fb367 100644 --- a/src/lj_ircall.h +++ b/src/lj_ircall.h | |||
@@ -203,7 +203,7 @@ typedef struct CCallInfo { | |||
203 | _(FFI, lj_carith_powi64, 2, N, I64, XA2_64|CCI_NOFPRCLOBBER) \ | 203 | _(FFI, lj_carith_powi64, 2, N, I64, XA2_64|CCI_NOFPRCLOBBER) \ |
204 | _(FFI, lj_carith_powu64, 2, N, U64, XA2_64|CCI_NOFPRCLOBBER) \ | 204 | _(FFI, lj_carith_powu64, 2, N, U64, XA2_64|CCI_NOFPRCLOBBER) \ |
205 | _(FFI, lj_cdata_newv, 4, S, CDATA, CCI_L) \ | 205 | _(FFI, lj_cdata_newv, 4, S, CDATA, CCI_L) \ |
206 | _(FFI, lj_cdata_setfin, 2, FN, P32, CCI_L) \ | 206 | _(FFI, lj_cdata_setfin, 4, S, NIL, CCI_L) \ |
207 | _(FFI, strlen, 1, L, INTP, 0) \ | 207 | _(FFI, strlen, 1, L, INTP, 0) \ |
208 | _(FFI, memcpy, 3, S, PTR, 0) \ | 208 | _(FFI, memcpy, 3, S, PTR, 0) \ |
209 | _(FFI, memset, 3, S, PTR, 0) \ | 209 | _(FFI, memset, 3, S, PTR, 0) \ |