aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-04-13 21:37:54 +0200
committerMike Pall <mike>2011-04-13 21:37:54 +0200
commit31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78 (patch)
tree28d9773177355112d1f819b7666bb2f1e7fb6048 /src
parent1fa0cc09b3c3a1567f805fa2c9e5214148b8bcd5 (diff)
downloadluajit-31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78.tar.gz
luajit-31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78.tar.bz2
luajit-31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78.zip
FFI: Fix cdata finalization.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.dep3
-rw-r--r--src/lj_asm.c6
-rw-r--r--src/lj_cdata.c19
-rw-r--r--src/lj_cdata.h1
-rw-r--r--src/lj_crecord.c26
-rw-r--r--src/lj_gc.c10
-rw-r--r--src/lj_ir.h1
7 files changed, 43 insertions, 23 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep
index c06060ce..4f5317b9 100644
--- a/src/Makefile.dep
+++ b/src/Makefile.dep
@@ -66,7 +66,8 @@ lj_ccall.o: lj_ccall.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
66lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 66lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
67 lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h 67 lj_err.h lj_errmsg.h lj_tab.h lj_ctype.h lj_gc.h lj_cdata.h lj_cconv.h
68lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 68lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
69 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cconv.h lj_cdata.h 69 lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_cconv.h \
70 lj_cdata.h
70lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h 71lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h
71lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 72lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \
72 lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \ 73 lj_err.h lj_errmsg.h lj_tab.h lj_str.h lj_udata.h lj_ctype.h lj_cconv.h \
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 8e7c98ee..a69f4461 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -2558,7 +2558,6 @@ static void asm_cnew(ASMState *as, IRIns *ir)
2558 lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i; 2558 lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op2)->i;
2559 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; 2559 const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
2560 IRRef args[2]; 2560 IRRef args[2];
2561 int gcfin = 0;
2562 lua_assert(sz != CTSIZE_INVALID); 2561 lua_assert(sz != CTSIZE_INVALID);
2563 2562
2564 args[0] = ASMREF_L; /* lua_State *L */ 2563 args[0] = ASMREF_L; /* lua_State *L */
@@ -2605,15 +2604,12 @@ static void asm_cnew(ASMState *as, IRIns *ir)
2605 } while (1); 2604 } while (1);
2606#endif 2605#endif
2607 lua_assert(sz == 4 || (sz == 8 && (LJ_64 || LJ_HASFFI))); 2606 lua_assert(sz == 4 || (sz == 8 && (LJ_64 || LJ_HASFFI)));
2608 } else {
2609 if (lj_ctype_meta(cts, typeid, MM_gc) != NULL)
2610 gcfin = LJ_GC_CDATA_FIN;
2611 } 2607 }
2612 2608
2613 /* Combine initialization of marked, gct and typeid. */ 2609 /* Combine initialization of marked, gct and typeid. */
2614 emit_movtomro(as, RID_ECX, RID_RET, offsetof(GCcdata, marked)); 2610 emit_movtomro(as, RID_ECX, RID_RET, offsetof(GCcdata, marked));
2615 emit_gri(as, XG_ARITHi(XOg_OR), RID_ECX, 2611 emit_gri(as, XG_ARITHi(XOg_OR), RID_ECX,
2616 (int32_t)((~LJ_TCDATA<<8)+(typeid<<16)+gcfin)); 2612 (int32_t)((~LJ_TCDATA<<8)+(typeid<<16)));
2617 emit_gri(as, XG_ARITHi(XOg_AND), RID_ECX, LJ_GC_WHITES); 2613 emit_gri(as, XG_ARITHi(XOg_AND), RID_ECX, LJ_GC_WHITES);
2618 emit_opgl(as, XO_MOVZXb, RID_ECX, gc.currentwhite); 2614 emit_opgl(as, XO_MOVZXb, RID_ECX, gc.currentwhite);
2619 2615
diff --git a/src/lj_cdata.c b/src/lj_cdata.c
index 53605e7e..d01cf62a 100644
--- a/src/lj_cdata.c
+++ b/src/lj_cdata.c
@@ -10,6 +10,7 @@
10#include "lj_gc.h" 10#include "lj_gc.h"
11#include "lj_err.h" 11#include "lj_err.h"
12#include "lj_str.h" 12#include "lj_str.h"
13#include "lj_tab.h"
13#include "lj_ctype.h" 14#include "lj_ctype.h"
14#include "lj_cconv.h" 15#include "lj_cconv.h"
15#include "lj_cdata.h" 16#include "lj_cdata.h"
@@ -74,6 +75,24 @@ void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd)
74 } 75 }
75} 76}
76 77
78TValue * LJ_FASTCALL lj_cdata_setfin(lua_State *L, GCcdata *cd)
79{
80 global_State *g = G(L);
81 GCtab *t = ctype_ctsG(g)->finalizer;
82 if (gcref(t->metatable)) {
83 /* Add cdata to finalizer table, if still enabled. */
84 TValue *tv, tmp;
85 setcdataV(L, &tmp, cd);
86 lj_gc_anybarriert(L, t);
87 tv = lj_tab_set(L, t, &tmp);
88 cd->marked |= LJ_GC_CDATA_FIN;
89 return tv;
90 } else {
91 /* Otherwise return dummy TValue. */
92 return &g->tmptv;
93 }
94}
95
77/* -- C data indexing ----------------------------------------------------- */ 96/* -- C data indexing ----------------------------------------------------- */
78 97
79/* Index C data by a TValue. Return CType and pointer. */ 98/* Index C data by a TValue. Return CType and pointer. */
diff --git a/src/lj_cdata.h b/src/lj_cdata.h
index 74cdab42..feb1bbf2 100644
--- a/src/lj_cdata.h
+++ b/src/lj_cdata.h
@@ -62,6 +62,7 @@ LJ_FUNC GCcdata *lj_cdata_newv(CTState *cts, 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);
65 66
66LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, 67LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key,
67 uint8_t **pp, CTInfo *qual); 68 uint8_t **pp, CTInfo *qual);
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 04c962d5..83c57063 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -710,20 +710,20 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
710 /* Handle __gc metamethod. */ 710 /* Handle __gc metamethod. */
711 fin = lj_ctype_meta(cts, id, MM_gc); 711 fin = lj_ctype_meta(cts, id, MM_gc);
712 if (fin) { 712 if (fin) {
713 RecordIndex ix; 713 TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd);
714 ix.idxchain = 0; 714 TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4));
715 settabV(J->L, &ix.tabv, cts->finalizer); 715 if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; }
716 ix.tab = lj_ir_ktab(J, cts->finalizer); 716 if (tvisfunc(fin)) {
717 setboolV(&ix.keyv, 0); /* The key is new. Dummy value is ok here. */ 717 emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin)));
718 ix.key = trcd; 718 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC));
719 copyTV(J->L, &ix.valv, fin); 719 } else if (tviscdata(fin)) {
720 if (tvisfunc(fin)) 720 emitir(IRT(IR_XSTORE, IRT_P32), trlo,
721 ix.val = lj_ir_kfunc(J, funcV(fin)); 721 lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA));
722 else if (tviscdata(fin)) 722 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA));
723 ix.val = lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA); 723 } else {
724 else
725 lj_trace_err(J, LJ_TRERR_BADTYPE); 724 lj_trace_err(J, LJ_TRERR_BADTYPE);
726 lj_record_idx(J, &ix); 725 }
726 J->needsnap = 1;
727 } 727 }
728 } 728 }
729} 729}
diff --git a/src/lj_gc.c b/src/lj_gc.c
index aba19d3f..7999e31f 100644
--- a/src/lj_gc.c
+++ b/src/lj_gc.c
@@ -494,12 +494,13 @@ static void gc_finalize(lua_State *L)
494 setgcrefnull(g->gc.mmudata); 494 setgcrefnull(g->gc.mmudata);
495 else 495 else
496 setgcrefr(gcref(g->gc.mmudata)->gch.nextgc, o->gch.nextgc); 496 setgcrefr(gcref(g->gc.mmudata)->gch.nextgc, o->gch.nextgc);
497 makewhite(g, o);
498#if LJ_HASFFI 497#if LJ_HASFFI
499 if (o->gch.gct == ~LJ_TCDATA) { 498 if (o->gch.gct == ~LJ_TCDATA) {
500 TValue tmp, *tv; 499 TValue tmp, *tv;
501 setgcrefr(o->gch.nextgc, g->gc.root); /* Add cdata back to the gc list. */ 500 /* Add cdata back to the GC list and make it white. */
501 setgcrefr(o->gch.nextgc, g->gc.root);
502 setgcref(g->gc.root, o); 502 setgcref(g->gc.root, o);
503 o->gch.marked = curwhite(g);
503 /* Resolve finalizer. */ 504 /* Resolve finalizer. */
504 setcdataV(L, &tmp, gco2cd(o)); 505 setcdataV(L, &tmp, gco2cd(o));
505 tv = lj_tab_set(L, ctype_ctsG(g)->finalizer, &tmp); 506 tv = lj_tab_set(L, ctype_ctsG(g)->finalizer, &tmp);
@@ -511,9 +512,10 @@ static void gc_finalize(lua_State *L)
511 return; 512 return;
512 } 513 }
513#endif 514#endif
514 /* Add userdata back to the main userdata list. */ 515 /* Add userdata back to the main userdata list and make it white. */
515 setgcrefr(o->gch.nextgc, mainthread(g)->nextgc); 516 setgcrefr(o->gch.nextgc, mainthread(g)->nextgc);
516 setgcref(mainthread(g)->nextgc, o); 517 setgcref(mainthread(g)->nextgc, o);
518 makewhite(g, o);
517 /* Resolve the __gc metamethod. */ 519 /* Resolve the __gc metamethod. */
518 mo = lj_meta_fastg(g, tabref(gco2ud(o)->metatable), MM_gc); 520 mo = lj_meta_fastg(g, tabref(gco2ud(o)->metatable), MM_gc);
519 if (mo) 521 if (mo)
@@ -542,7 +544,7 @@ void lj_gc_finalize_cdata(lua_State *L)
542 if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) { 544 if (!tvisnil(&node[i].val) && tviscdata(&node[i].key)) {
543 GCobj *o = gcV(&node[i].key); 545 GCobj *o = gcV(&node[i].key);
544 TValue tmp; 546 TValue tmp;
545 o->gch.marked &= ~LJ_GC_CDATA_FIN; 547 o->gch.marked = curwhite(g);
546 copyTV(L, &tmp, &node[i].val); 548 copyTV(L, &tmp, &node[i].val);
547 setnilV(&node[i].val); 549 setnilV(&node[i].val);
548 gc_call_finalizer(g, L, &tmp, o); 550 gc_call_finalizer(g, L, &tmp, o);
diff --git a/src/lj_ir.h b/src/lj_ir.h
index c46bbbe0..5659ba73 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -279,6 +279,7 @@ typedef struct CCallInfo {
279 _(lj_carith_modu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \ 279 _(lj_carith_modu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
280 _(lj_carith_powi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \ 280 _(lj_carith_powi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \
281 _(lj_carith_powu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \ 281 _(lj_carith_powu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \
282 _(lj_cdata_setfin, 2, FN, P32, CCI_L) \
282 _(strlen, 1, N, INTP, 0) \ 283 _(strlen, 1, N, INTP, 0) \
283 _(memcpy, 3, S, PTR, 0) \ 284 _(memcpy, 3, S, PTR, 0) \
284 _(memset, 3, S, PTR, 0) 285 _(memset, 3, S, PTR, 0)