diff options
author | Mike Pall <mike> | 2011-04-13 21:37:54 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-04-13 21:37:54 +0200 |
commit | 31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78 (patch) | |
tree | 28d9773177355112d1f819b7666bb2f1e7fb6048 /src | |
parent | 1fa0cc09b3c3a1567f805fa2c9e5214148b8bcd5 (diff) | |
download | luajit-31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78.tar.gz luajit-31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78.tar.bz2 luajit-31e0774a9e6dfcc8ddfa6669fb225473fbc4ad78.zip |
FFI: Fix cdata finalization.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.dep | 3 | ||||
-rw-r--r-- | src/lj_asm.c | 6 | ||||
-rw-r--r-- | src/lj_cdata.c | 19 | ||||
-rw-r--r-- | src/lj_cdata.h | 1 | ||||
-rw-r--r-- | src/lj_crecord.c | 26 | ||||
-rw-r--r-- | src/lj_gc.c | 10 | ||||
-rw-r--r-- | src/lj_ir.h | 1 |
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 \ | |||
66 | lj_cconv.o: lj_cconv.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 66 | lj_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 |
68 | lj_cdata.o: lj_cdata.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 68 | lj_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 | ||
70 | lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h | 71 | lj_char.o: lj_char.c lj_char.h lj_def.h lua.h luaconf.h |
71 | lj_clib.o: lj_clib.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 72 | lj_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 | ||
78 | TValue * 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 | ||
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 | 66 | ||
66 | LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, | 67 | LJ_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) |