]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
FFI: Record loads/stores to external variables in namespaces.
authorMike Pall <mike>
Tue, 11 Oct 2011 18:56:57 +0000 (20:56 +0200)
committerMike Pall <mike>
Tue, 11 Oct 2011 18:58:04 +0000 (20:58 +0200)
doc/ext_ffi_semantics.html
src/lib_ffi.c
src/lj_crecord.c

index 80939f33d110b8c11d469d046f866693601906b4..9016a8a63d00e8b15d55d31e76234ccc2fa360de 100644 (file)
@@ -991,7 +991,6 @@ value.</li>
 <li>Calls to ctype metamethods which are not plain functions.</li>
 <li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype
 <tt>__index</tt> tables.</li>
-<li>Accesses to external variables in C&nbsp;library namespaces.</li>
 <li><tt>tostring()</tt> for cdata types.</li>
 <li>Calls to the following <a href="ext_ffi_api.html">ffi.* API</a>
 functions: <tt>cdef</tt>, <tt>load</tt>, <tt>typeof</tt>,
index 582e9bf706c3d5c7a89ec63499ab1a72a68c7271..82942e44c3616af5c668170a1a45b12775c93715 100644 (file)
@@ -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;
index 96b62efe2ab35d3d9eea39be7862a46265562b10..c688caa35b24b075f77aaa62d7d43d6c4d84cc96 100644 (file)
@@ -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);
       }