diff --git a/doc/ext_ffi_semantics.html b/doc/ext_ffi_semantics.html index 80939f33..9016a8a6 100644 --- a/doc/ext_ffi_semantics.html +++ b/doc/ext_ffi_semantics.html @@ -991,7 +991,6 @@ value.
  • Calls to ctype metamethods which are not plain functions.
  • ctype __newindex tables and non-string lookups in ctype __index tables.
  • -
  • Accesses to external variables in C library namespaces.
  • tostring() for cdata types.
  • Calls to the following ffi.* API functions: cdef, load, typeof, diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 582e9bf7..82942e44 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c @@ -325,7 +325,7 @@ static TValue *ffi_clib_index(lua_State *L) return lj_clib_index(L, cl, strV(o+1)); } -LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index) +LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index 1) { TValue *tv = ffi_clib_index(L); if (tviscdata(tv)) { @@ -335,7 +335,9 @@ LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index) if (ctype_isextern(s->info)) { CTypeID sid = ctype_cid(s->info); void *sp = *(void **)cdataptr(cd); - if (lj_cconv_tv_ct(cts, ctype_raw(cts, sid), sid, L->top-1, sp)) + CType *ct = ctype_raw(cts, sid); + if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct); + if (lj_cconv_tv_ct(cts, ct, sid, L->top-1, sp)) lj_gc_check(L); return 1; } @@ -344,7 +346,7 @@ LJLIB_CF(ffi_clib___index) LJLIB_REC(clib_index) return 1; } -LJLIB_CF(ffi_clib___newindex) +LJLIB_CF(ffi_clib___newindex) LJLIB_REC(clib_index 0) { TValue *tv = ffi_clib_index(L); TValue *o = L->base+2; diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 96b62efe..c688caa3 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -1031,6 +1031,7 @@ void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd) CType *ct; CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX); cTValue *tv = lj_tab_getstr(cl->cache, name); + rd->nres = rd->data; if (id && tv && !tvisnil(tv)) { /* Specialize to the symbol name and make the result a constant. */ emitir(IRTG(IR_EQ, IRT_STR), J->base[1], lj_ir_kstr(J, name)); @@ -1041,7 +1042,21 @@ void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd) else J->base[0] = lj_ir_kint(J, (int32_t)ct->size); } else if (ctype_isextern(ct->info)) { - lj_trace_err(J, LJ_TRERR_BADTYPE); /* NYI: access extern variables. */ + CTypeID sid = ctype_cid(ct->info); + void *sp = *(void **)cdataptr(cdataV(tv)); + TRef ptr; + ct = ctype_raw(cts, sid); + if (rd->data && ctype_isenum(ct->info)) ct = ctype_child(cts, ct); + if (LJ_64 && !checkptr32(sp)) + ptr = lj_ir_kintp(J, (uintptr_t)sp); + else + ptr = lj_ir_kptr(J, sp); + if (rd->data) { + J->base[0] = crec_tv_ct(J, ct, sid, ptr); + } else { + J->needsnap = 1; + crec_ct_tv(J, ct, ptr, J->base[2], &rd->argv[2]); + } } else { J->base[0] = lj_ir_kgc(J, obj2gco(cdataV(tv)), IRT_CDATA); }