Browse Source

FFI: Record C library namespace lookups.

Mike Pall 14 years ago
parent
commit
14f5103764
8 changed files with 53 additions and 11 deletions
  1. 3 3
      src/Makefile.dep
  2. 1 1
      src/lib_ffi.c
  3. 0 4
      src/lj_clib.c
  4. 3 0
      src/lj_clib.h
  5. 34 0
      src/lj_crecord.c
  6. 2 0
      src/lj_crecord.h
  7. 9 3
      src/lj_opt_fold.c
  8. 1 0
      src/lj_traceerr.h

+ 3 - 3
src/Makefile.dep

@@ -75,9 +75,9 @@ lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_cparse.h lj_frame.h \
  lj_bc.h lj_vm.h lj_char.h
 lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
- lj_err.h lj_errmsg.h lj_str.h lj_ctype.h lj_gc.h lj_cparse.h lj_cconv.h \
- lj_ir.h lj_jit.h lj_iropt.h lj_trace.h lj_dispatch.h lj_bc.h \
- lj_traceerr.h lj_ffrecord.h lj_crecord.h
+ lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h lj_gc.h lj_cparse.h \
+ lj_cconv.h lj_clib.h lj_ir.h lj_jit.h lj_iropt.h lj_trace.h \
+ lj_dispatch.h lj_bc.h lj_traceerr.h lj_ffrecord.h lj_crecord.h
 lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \
  lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_ctype.h
 lj_dispatch.o: lj_dispatch.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \

+ 1 - 1
src/lib_ffi.c

@@ -239,7 +239,7 @@ static TValue *ffi_clib_index(lua_State *L)
   return lj_clib_index(L, cl, strV(o+1));
 }
 
-LJLIB_CF(ffi_clib___index)
+LJLIB_CF(ffi_clib___index)	LJLIB_REC(clib_index)
 {
   TValue *tv = ffi_clib_index(L);
   if (tviscdata(tv)) {

+ 0 - 4
src/lj_clib.c

@@ -222,10 +222,6 @@ static void *clib_getsym(CLibrary *cl, const char *name)
 
 /* -- C library indexing -------------------------------------------------- */
 
-/* Namespace for C library indexing. */
-#define CLNS_INDEX \
-  ((1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
-
 #if LJ_TARGET_X86 && LJ_ABI_WIN
 /* Compute argument size for fastcall/stdcall functions. */
 static CTSize clib_func_argsize(CTState *cts, CType *ct)

+ 3 - 0
src/lj_clib.h

@@ -10,6 +10,9 @@
 
 #if LJ_HASFFI
 
+/* Namespace for C library indexing. */
+#define CLNS_INDEX	((1u<<CT_FUNC)|(1u<<CT_EXTERN)|(1u<<CT_CONSTVAL))
+
 /* C library namespace. */
 typedef struct CLibrary {
   void *handle;		/* Opaque handle for dynamic library loader. */

+ 34 - 0
src/lj_crecord.c

@@ -12,9 +12,11 @@
 
 #include "lj_err.h"
 #include "lj_str.h"
+#include "lj_tab.h"
 #include "lj_ctype.h"
 #include "lj_cparse.h"
 #include "lj_cconv.h"
+#include "lj_clib.h"
 #include "lj_ir.h"
 #include "lj_jit.h"
 #include "lj_iropt.h"
@@ -837,6 +839,38 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
   }
 }
 
+/* -- C library namespace metamethods ------------------------------------- */
+
+void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd)
+{
+  CTState *cts = ctype_ctsG(J2G(J));
+  if (tref_isudata(J->base[0]) && tref_isstr(J->base[1]) &&
+      udataV(&rd->argv[0])->udtype == UDTYPE_FFI_CLIB) {
+    CLibrary *cl = (CLibrary *)uddata(udataV(&rd->argv[0]));
+    GCstr *name = strV(&rd->argv[1]);
+    CType *ct;
+    CTypeID id = lj_ctype_getname(cts, &ct, name, CLNS_INDEX);
+    cTValue *tv = lj_tab_getstr(cl->cache, name);
+    if (id && tv && tviscdata(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));
+      if (ctype_isconstval(ct->info)) {
+	if (ct->size >= 0x80000000u &&
+	    (ctype_child(cts, ct)->info & CTF_UNSIGNED))
+	  J->base[0] = lj_ir_knum(J, (lua_Number)(uint32_t)ct->size);
+	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. */
+      } else {
+	J->base[0] = lj_ir_kgc(J, obj2gco(cdataV(tv)), IRT_CDATA);
+      }
+    } else {
+      lj_trace_err(J, LJ_TRERR_NOCACHE);
+    }
+  }  /* else: interpreter will throw. */
+}
+
 /* -- FFI library functions ----------------------------------------------- */
 
 void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)

+ 2 - 0
src/lj_crecord.h

@@ -14,6 +14,7 @@
 LJ_FUNC void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd);
+LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
 LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
@@ -21,6 +22,7 @@ LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
 #define recff_cdata_index	recff_nyi
 #define recff_cdata_call	recff_nyi
 #define recff_cdata_arith	recff_nyi
+#define recff_clib_index	recff_nyi
 #define recff_ffi_new		recff_nyi
 #define recff_ffi_string	recff_nyi
 #endif

+ 9 - 3
src/lj_opt_fold.c

@@ -1768,12 +1768,18 @@ LJFOLDF(fload_cdata_typeid_kgc)
   return NEXTFOLD;
 }
 
-/* The content of int64 cdata objects is immutable. */
+/* Get the contents of immutable cdata objects. */
+LJFOLD(FLOAD KGC IRFL_CDATA_PTR)
 LJFOLD(FLOAD KGC IRFL_CDATA_INT64)
 LJFOLDF(fload_cdata_int64_kgc)
 {
-  if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD))
-    return INT64FOLD(*(uint64_t *)cdataptr(ir_kcdata(fleft)));
+  if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) {
+    void *p = cdataptr(ir_kcdata(fleft));
+    if (irt_is64(fins->t))
+      return INT64FOLD(*(uint64_t *)p);
+    else
+      return INTFOLD(*(int32_t *)p);
+  }
   return NEXTFOLD;
 }
 

+ 1 - 0
src/lj_traceerr.h

@@ -35,6 +35,7 @@ TREDEF(IDXLOOP,	"looping index lookup")
 TREDEF(NYITMIX,	"NYI: mixed sparse/dense table")
 
 /* Recording C data operations. */
+TREDEF(NOCACHE,	"symbol not in cache")
 TREDEF(NYICONV,	"NYI: unsupported C type conversion")
 
 /* Optimizations. */