diff options
| author | Mike Pall <mike> | 2010-12-30 12:16:25 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-12-30 12:16:25 +0100 |
| commit | 4668b229de64a839857391808c90f92290125ad8 (patch) | |
| tree | c5ed7341b02e478c636c4422d3968a00c0e44a39 /src | |
| parent | 158de60b8c5a46b3f00c00ae54ed026ef46487b3 (diff) | |
| download | luajit-4668b229de64a839857391808c90f92290125ad8.tar.gz luajit-4668b229de64a839857391808c90f92290125ad8.tar.bz2 luajit-4668b229de64a839857391808c90f92290125ad8.zip | |
FFI: Add missing GC steps for implicit allocations.
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib_ffi.c | 12 | ||||
| -rw-r--r-- | src/lj_cconv.c | 10 | ||||
| -rw-r--r-- | src/lj_cconv.h | 6 | ||||
| -rw-r--r-- | src/lj_cdata.c | 9 | ||||
| -rw-r--r-- | 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) | |||
| 123 | if (!(o+1 < L->top && tviscdata(o))) /* Also checks for presence of key. */ | 123 | if (!(o+1 < L->top && tviscdata(o))) /* Also checks for presence of key. */ |
| 124 | lj_err_argt(L, 1, LUA_TCDATA); | 124 | lj_err_argt(L, 1, LUA_TCDATA); |
| 125 | ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual); | 125 | ct = lj_cdata_index(cts, cdataV(o), o+1, &p, &qual); |
| 126 | lj_cdata_get(cts, ct, L->top-1, p); | 126 | if (lj_cdata_get(cts, ct, L->top-1, p)) |
| 127 | lj_gc_check(L); | ||
| 127 | return 1; | 128 | return 1; |
| 128 | } | 129 | } |
| 129 | 130 | ||
| @@ -210,6 +211,7 @@ static int ffi_arith_ptr(lua_State *L, CTState *cts, FFIArith *fa, MMS mm) | |||
| 210 | cd = lj_cdata_new(cts, id, CTSIZE_PTR); | 211 | cd = lj_cdata_new(cts, id, CTSIZE_PTR); |
| 211 | *(uint8_t **)cdataptr(cd) = pp; | 212 | *(uint8_t **)cdataptr(cd) = pp; |
| 212 | setcdataV(L, L->top-1, cd); | 213 | setcdataV(L, L->top-1, cd); |
| 214 | lj_gc_check(L); | ||
| 213 | return 1; | 215 | return 1; |
| 214 | } | 216 | } |
| 215 | 217 | ||
| @@ -265,6 +267,7 @@ static int ffi_arith_int64(lua_State *L, CTState *cts, FFIArith *fa, MMS mm) | |||
| 265 | case MM_unm: *up = -u0; break; | 267 | case MM_unm: *up = -u0; break; |
| 266 | default: lua_assert(0); break; | 268 | default: lua_assert(0); break; |
| 267 | } | 269 | } |
| 270 | lj_gc_check(L); | ||
| 268 | return 1; | 271 | return 1; |
| 269 | } | 272 | } |
| 270 | return 0; | 273 | return 0; |
| @@ -335,14 +338,16 @@ LJLIB_CF(ffi_meta___tostring) | |||
| 335 | CType *ct = ctype_raw(ctype_cts(L), id); | 338 | CType *ct = ctype_raw(ctype_cts(L), id); |
| 336 | if (ctype_iscomplex(ct->info)) { | 339 | if (ctype_iscomplex(ct->info)) { |
| 337 | setstrV(L, L->top-1, lj_ctype_repr_complex(L, cdataptr(cd), ct->size)); | 340 | setstrV(L, L->top-1, lj_ctype_repr_complex(L, cdataptr(cd), ct->size)); |
| 338 | return 1; | 341 | goto checkgc; |
| 339 | } else if (ct->size == 8 && ctype_isinteger(ct->info)) { | 342 | } else if (ct->size == 8 && ctype_isinteger(ct->info)) { |
| 340 | setstrV(L, L->top-1, lj_ctype_repr_int64(L, *(uint64_t *)cdataptr(cd), | 343 | setstrV(L, L->top-1, lj_ctype_repr_int64(L, *(uint64_t *)cdataptr(cd), |
| 341 | (ct->info & CTF_UNSIGNED))); | 344 | (ct->info & CTF_UNSIGNED))); |
| 342 | return 1; | 345 | goto checkgc; |
| 343 | } | 346 | } |
| 344 | } | 347 | } |
| 345 | lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), cdataptr(cd)); | 348 | lj_str_pushf(L, msg, strdata(lj_ctype_repr(L, id, NULL)), cdataptr(cd)); |
| 349 | checkgc: | ||
| 350 | lj_gc_check(L); | ||
| 346 | return 1; | 351 | return 1; |
| 347 | } | 352 | } |
| 348 | 353 | ||
| @@ -402,6 +407,7 @@ LJLIB_CF(ffi_typeof) | |||
| 402 | GCcdata *cd = lj_cdata_new(cts, CTID_CTYPEID, 4); | 407 | GCcdata *cd = lj_cdata_new(cts, CTID_CTYPEID, 4); |
| 403 | *(CTypeID *)cdataptr(cd) = id; | 408 | *(CTypeID *)cdataptr(cd) = id; |
| 404 | setcdataV(L, L->top-1, cd); | 409 | setcdataV(L, L->top-1, cd); |
| 410 | lj_gc_check(L); | ||
| 405 | return 1; | 411 | return 1; |
| 406 | } | 412 | } |
| 407 | 413 | ||
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. */ | |||
| 375 | /* -- C type to TValue conversion ----------------------------------------- */ | 375 | /* -- C type to TValue conversion ----------------------------------------- */ |
| 376 | 376 | ||
| 377 | /* Convert C type to TValue. Caveat: expects to get the raw CType! */ | 377 | /* Convert C type to TValue. Caveat: expects to get the raw CType! */ |
| 378 | void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, | 378 | int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, |
| 379 | TValue *o, uint8_t *sp) | 379 | TValue *o, uint8_t *sp) |
| 380 | { | 380 | { |
| 381 | CTInfo sinfo = s->info; | 381 | CTInfo sinfo = s->info; |
| 382 | lua_assert(!ctype_isenum(sinfo)); | 382 | lua_assert(!ctype_isenum(sinfo)); |
| @@ -398,9 +398,11 @@ void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, | |||
| 398 | setboolV(o, tmpbool); | 398 | setboolV(o, tmpbool); |
| 399 | else | 399 | else |
| 400 | lua_assert(tvisnum(o)); | 400 | lua_assert(tvisnum(o)); |
| 401 | return 0; | ||
| 401 | } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { | 402 | } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { |
| 402 | /* Create reference. */ | 403 | /* Create reference. */ |
| 403 | setcdataV(cts->L, o, lj_cdata_newref(cts, sp, sid)); | 404 | setcdataV(cts->L, o, lj_cdata_newref(cts, sp, sid)); |
| 405 | return 1; /* Need GC step. */ | ||
| 404 | } else { | 406 | } else { |
| 405 | GCcdata *cd; | 407 | GCcdata *cd; |
| 406 | CTSize sz; | 408 | CTSize sz; |
| @@ -411,11 +413,12 @@ void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, | |||
| 411 | cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz); | 413 | cd = lj_cdata_new(cts, ctype_typeid(cts, s), sz); |
| 412 | setcdataV(cts->L, o, cd); | 414 | setcdataV(cts->L, o, cd); |
| 413 | memcpy(cdataptr(cd), sp, sz); | 415 | memcpy(cdataptr(cd), sp, sz); |
| 416 | return 1; /* Need GC step. */ | ||
| 414 | } | 417 | } |
| 415 | } | 418 | } |
| 416 | 419 | ||
| 417 | /* Convert bitfield to TValue. */ | 420 | /* Convert bitfield to TValue. */ |
| 418 | void lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) | 421 | int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) |
| 419 | { | 422 | { |
| 420 | CTInfo info = s->info; | 423 | CTInfo info = s->info; |
| 421 | CTSize pos, bsz; | 424 | CTSize pos, bsz; |
| @@ -445,6 +448,7 @@ void lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp) | |||
| 445 | lua_assert(bsz == 1); | 448 | lua_assert(bsz == 1); |
| 446 | setboolV(o, (val >> pos) & 1); | 449 | setboolV(o, (val >> pos) & 1); |
| 447 | } | 450 | } |
| 451 | return 0; /* No GC step needed. */ | ||
| 448 | } | 452 | } |
| 449 | 453 | ||
| 450 | /* -- TValue to C type conversion ----------------------------------------- */ | 454 | /* -- 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) | |||
| 52 | LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); | 52 | LJ_FUNC int lj_cconv_compatptr(CTState *cts, CType *d, CType *s, CTInfo flags); |
| 53 | LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, | 53 | LJ_FUNC void lj_cconv_ct_ct(CTState *cts, CType *d, CType *s, |
| 54 | uint8_t *dp, uint8_t *sp, CTInfo flags); | 54 | uint8_t *dp, uint8_t *sp, CTInfo flags); |
| 55 | LJ_FUNC void lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, | 55 | LJ_FUNC int lj_cconv_tv_ct(CTState *cts, CType *s, CTypeID sid, |
| 56 | TValue *o, uint8_t *sp); | 56 | TValue *o, uint8_t *sp); |
| 57 | LJ_FUNC void lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp); | 57 | LJ_FUNC int lj_cconv_tv_bf(CTState *cts, CType *s, TValue *o, uint8_t *sp); |
| 58 | LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d, | 58 | LJ_FUNC void lj_cconv_ct_tv(CTState *cts, CType *d, |
| 59 | uint8_t *dp, TValue *o, CTInfo flags); | 59 | uint8_t *dp, TValue *o, CTInfo flags); |
| 60 | LJ_FUNC void lj_cconv_bf_tv(CTState *cts, CType *d, uint8_t *dp, TValue *o); | 60 | 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) | |||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | /* Get C data value and convert to TValue. */ | 156 | /* Get C data value and convert to TValue. */ |
| 157 | void lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) | 157 | int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) |
| 158 | { | 158 | { |
| 159 | CTypeID sid; | 159 | CTypeID sid; |
| 160 | 160 | ||
| 161 | if (ctype_isconstval(s->info)) { | 161 | if (ctype_isconstval(s->info)) { |
| 162 | cdata_getconst(cts, o, s); | 162 | cdata_getconst(cts, o, s); |
| 163 | return; | 163 | return 0; /* No GC step needed. */ |
| 164 | } else if (ctype_isbitfield(s->info)) { | 164 | } else if (ctype_isbitfield(s->info)) { |
| 165 | lj_cconv_tv_bf(cts, s, o, sp); | 165 | return lj_cconv_tv_bf(cts, s, o, sp); |
| 166 | return; | ||
| 167 | } | 166 | } |
| 168 | 167 | ||
| 169 | /* Get child type of pointer/array/field. */ | 168 | /* Get child type of pointer/array/field. */ |
| @@ -183,7 +182,7 @@ void lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp) | |||
| 183 | while (ctype_isattrib(s->info) || ctype_isenum(s->info)) | 182 | while (ctype_isattrib(s->info) || ctype_isenum(s->info)) |
| 184 | s = ctype_child(cts, s); | 183 | s = ctype_child(cts, s); |
| 185 | 184 | ||
| 186 | lj_cconv_tv_ct(cts, s, sid, o, sp); | 185 | return lj_cconv_tv_ct(cts, s, sid, o, sp); |
| 187 | } | 186 | } |
| 188 | 187 | ||
| 189 | /* -- C data setters ------------------------------------------------------ */ | 188 | /* -- 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); | |||
| 62 | 62 | ||
| 63 | LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, | 63 | LJ_FUNC CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, |
| 64 | uint8_t **pp, CTInfo *qual); | 64 | uint8_t **pp, CTInfo *qual); |
| 65 | LJ_FUNC void lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp); | 65 | LJ_FUNC int lj_cdata_get(CTState *cts, CType *s, TValue *o, uint8_t *sp); |
| 66 | LJ_FUNC void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, | 66 | LJ_FUNC void lj_cdata_set(CTState *cts, CType *d, uint8_t *dp, TValue *o, |
| 67 | CTInfo qual); | 67 | CTInfo qual); |
| 68 | 68 | ||
