From 4668b229de64a839857391808c90f92290125ad8 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Thu, 30 Dec 2010 12:16:25 +0100 Subject: [PATCH] FFI: Add missing GC steps for implicit allocations. --- src/lib_ffi.c | 12 +++++++++--- src/lj_cconv.c | 10 +++++++--- src/lj_cconv.h | 6 +++--- src/lj_cdata.c | 9 ++++----- src/lj_cdata.h | 2 +- 5 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/lib_ffi.c b/src/lib_ffi.c index c674582d..414f1d2f 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -123,7 +123,8 @@ LJLIB_CF(ffi_meta___index) LJLIB_REC(cdata_index 0) if (!(o+1 < L->top && tviscdata(o))) /* Also checks for presence of key. */ lj_err_argt(L, 1, LUA_TCDATA); ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual); - lj_cdata_get(cts, ct, L->top-1, p); + if (lj_cdata_get(cts, ct, L->top-1, p)) + lj_gc_check(L); return 1; } @@ -210,6 +211,7 @@ static int ffi_arith_ptr(lua_State *L, CTState *cts, FFIArith *fa, MMS mm) cd = lj_cdata_new(cts, id, CTSIZE_PTR); *(uint8_t **)cdataptr(cd) = pp; setcdataV(L, L->top-1, cd); + lj_gc_check(L); return 1; } @@ -265,6 +267,7 @@ static int ffi_arith_int64(lua_State *L, CTState *cts, FFIArith *fa, MMS mm) case MM_unm: *up = -u0; break; default: lua_assert(0); break; } + lj_gc_check(L); return 1; } return 0; @@ -335,14 +338,16 @@ LJLIB_CF(ffi_meta___tostring) CType *ct = ctype_raw(ctype_cts(L), id); if (ctype_iscomplex(ct->info)) { setstrV(L, L->top-1, lj_ctype_repr_complex(L, cdataptr(cd), ct->size)); - return 1; + goto checkgc; } else if (ct->size == 8 && ctype_isinteger(ct->info)) { setstrV(L, L->top-1, lj_ctype_repr_int64(L, *(uint64_t *)cdataptr(cd), (ct->info & CTF_UNSIGNED))); - return 1; + goto checkgc; } } lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), cdataptr(cd)); +checkgc: + lj_gc_check(L); return 1; } @@ -402,6 +407,7 @@ LJLIB_CF(ffi_typeof) GCcdata *cd = lj_cdata_new(cts, CTID_CTYPEID, 4); *(CTypeID *)cdataptr(cd) = id; setcdataV(L, L->top-1, cd); + lj_gc_check(L); return 1; } diff --git a/src/lj_cconv.c b/src/lj_cconv.c index 642a4852..5df33d04 100644 --- a/src/lj_cconv.c +++ b/src/lj_cconv.c @@ -375,8 +375,8 @@ copyval: /* Copy value. */ /* -- C type to TValue conversion ----------------------------------------- */ /* Convert C type to TValue. Caveat: expects to get the raw CType! */ -void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, - TValue *o, uint8_t *sp) +int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, + TValue *o, uint8_t *sp) { CTInfo sinfo = s->info; lua_assert(!ctype_isenum(sinfo)); @@ -398,9 +398,11 @@ void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, setboolV(o, tmpbool); else lua_assert(tvisnum(o)); + return 0; } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { /* Create reference. */ setcdataV(cts->L, o, lj_cdata_newref(cts, sp, sid)); + return 1; /* Need GC step. */ } else { GCcdata *cd; CTSize sz; @@ -411,11 +413,12 @@ void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz); setcdataV(cts->L, o, cd); memcpy(cdataptr(cd), sp, sz); + return 1; /* Need GC step. */ } } /* Convert bitfield to TValue. */ -void lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) +int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) { CTInfo info = s->info; CTSize pos, bsz; @@ -445,6 +448,7 @@ void lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) lua_assert(bsz == 1); setboolV(o, (val >> pos) & 1); } + return 0; /* No GC step needed. */ } /* -- TValue to C type conversion ----------------------------------------- */ diff --git a/src/lj_cconv.h b/src/lj_cconv.h index dd2f2c40..ee16a845 100644 --- a/src/lj_cconv.h +++ b/src/lj_cconv.h @@ -52,9 +52,9 @@ static LJ_AINLINE uint32_t cconv_idx(CTInfo info) LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, uint8_t *dp, uint8_t *sp, CTInfo flags); -LJ_FUNC void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, - TValue *o, uint8_t *sp); -LJ_FUNC void lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp); +LJ_FUNC int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, + TValue *o, uint8_t *sp); +LJ_FUNC int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp); LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o, CTInfo flags); LJ_FUNC void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o); diff --git a/src/lj_cdata.c b/src/lj_cdata.c index 499dbc4d..71453e27 100644 --- a/src/lj_cdata.c +++ b/src/lj_cdata.c @@ -154,16 +154,15 @@ static void cdata_getconst(CTState *cts, TValue *o, CType *ct) } /* Get C data value and convert to TValue. */ -void lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) +int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) { CTypeID sid; if (ctype_isconstval(s->info)) { cdata_getconst(cts, o, s); - return; + return 0; /* No GC step needed. */ } else if (ctype_isbitfield(s->info)) { - lj_cconv_tv_bf(cts, s, o, sp); - return; + return lj_cconv_tv_bf(cts, s, o, sp); } /* Get child type of pointer/array/field. */ @@ -183,7 +182,7 @@ void lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) while (ctype_isattrib(s->info) || ctype_isenum(s->info)) s = ctype_child(cts, s); - lj_cconv_tv_ct(cts, s, sid, o, sp); + return lj_cconv_tv_ct(cts, s, sid, o, sp); } /* -- C data setters ------------------------------------------------------ */ diff --git a/src/lj_cdata.h b/src/lj_cdata.h index 5de82067..564d827f 100644 --- a/src/lj_cdata.h +++ b/src/lj_cdata.h @@ -62,7 +62,7 @@ LJ_FUNC void LJ_FASTCALL lj_cdata_free(global_State *g, GCcdata *cd); LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, uint8_t **pp, CTInfo *qual); -LJ_FUNC void lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp); +LJ_FUNC int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp); LJ_FUNC void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, CTInfo qual);