aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2013-05-24 17:44:55 +0200
committerMike Pall <mike>2013-05-24 17:44:55 +0200
commit992f7d4b71d0f39266c9b2d7f8ce28c278afb667 (patch)
treef12f1ec3a7df3dee5035b499a98292a2f78aa8f1
parent4c1f9dd0f7fdbf79ed62588c64417d6238fd5c51 (diff)
downloadluajit-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.c10
-rw-r--r--src/lj_cdata.c15
-rw-r--r--src/lj_cdata.h3
-rw-r--r--src/lj_crecord.c24
-rw-r--r--src/lj_ircall.h2
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
78TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd) 78void 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
64LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd); 64LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd);
65LJ_FUNCA TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd); 65LJ_FUNC void lj_cdata_setfin(lua_State *L, GCcdata *cd, GCobj *obj,
66 uint32_t it);
66 67
67LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, 68LJ_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. */
866static void crec_finalizer(jit_State *J, TRef trcd, cTValue *fin) 866static 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)
1648void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) 1644void 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) \