Browse Source

FFI: Add cdata object type.

Mike Pall 14 years ago
parent
commit
2fd1292955
7 changed files with 47 additions and 10 deletions
  1. 2 0
      lib/dump.lua
  2. 2 1
      src/lib_base.c
  3. 4 2
      src/lj_api.c
  4. 1 0
      src/lj_gc.c
  5. 2 1
      src/lj_ir.h
  6. 2 2
      src/lj_obj.c
  7. 34 4
      src/lj_obj.h

+ 2 - 0
lib/dump.lua

@@ -134,6 +134,7 @@ local irtype_text = {
   "pro",
   "pro",
   "fun",
   "fun",
   "t09",
   "t09",
+  "cdt",
   "tab",
   "tab",
   "udt",
   "udt",
   "num",
   "num",
@@ -155,6 +156,7 @@ local colortype_ansi = {
   "%s",
   "%s",
   "\027[1m%s\027[m",
   "\027[1m%s\027[m",
   "%s",
   "%s",
+  "\027[33m%s\027[m",
   "\027[31m%s\027[m",
   "\027[31m%s\027[m",
   "\027[36m%s\027[m",
   "\027[36m%s\027[m",
   "\027[34m%s\027[m",
   "\027[34m%s\027[m",

+ 2 - 1
src/lib_base.c

@@ -55,8 +55,9 @@ LJLIB_PUSH("thread")
 LJLIB_PUSH("proto")
 LJLIB_PUSH("proto")
 LJLIB_PUSH("function")
 LJLIB_PUSH("function")
 LJLIB_PUSH("trace")
 LJLIB_PUSH("trace")
+LJLIB_PUSH("cdata")
 LJLIB_PUSH("table")
 LJLIB_PUSH("table")
-LJLIB_PUSH(top-8)  /* userdata */
+LJLIB_PUSH(top-9)  /* userdata */
 LJLIB_PUSH("number")
 LJLIB_PUSH("number")
 LJLIB_ASM_(type)		LJLIB_REC(.)
 LJLIB_ASM_(type)		LJLIB_REC(.)
 /* Recycle the lj_lib_checkany(L, 1) from assert. */
 /* Recycle the lj_lib_checkany(L, 1) from assert. */

+ 4 - 2
src/lj_api.c

@@ -197,9 +197,9 @@ LUA_API int lua_type(lua_State *L, int idx)
   } else {  /* Magic internal/external tag conversion. ORDER LJ_T */
   } else {  /* Magic internal/external tag conversion. ORDER LJ_T */
     uint32_t t = ~itype(o);
     uint32_t t = ~itype(o);
 #if LJ_64
 #if LJ_64
-    int tt = (int)((U64x(7506,98042110) >> 4*t) & 15u);
+    int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u);
 #else
 #else
-    int tt = (int)(((t < 8 ? 0x98042110 : 0x7506) >> 4*(t&7)) & 15u);
+    int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u);
 #endif
 #endif
     lua_assert(tt != LUA_TNIL || tvisnil(o));
     lua_assert(tt != LUA_TNIL || tvisnil(o));
     return tt;
     return tt;
@@ -525,6 +525,8 @@ LUA_API const void *lua_topointer(lua_State *L, int idx)
     return uddata(udataV(o));
     return uddata(udataV(o));
   else if (tvislightud(o))
   else if (tvislightud(o))
     return lightudV(o);
     return lightudV(o);
+  else if (tviscdata(o))
+    return cdataptr(cdataV(o));
   else if (tvisgcv(o))
   else if (tvisgcv(o))
     return gcV(o);
     return gcV(o);
   else
   else

+ 1 - 0
src/lj_gc.c

@@ -373,6 +373,7 @@ static const GCFreeFunc gc_freefunc[] = {
 #else
 #else
   (GCFreeFunc)0,
   (GCFreeFunc)0,
 #endif
 #endif
+  (GCFreeFunc)0,  /* Placeholder for C data. */
   (GCFreeFunc)lj_tab_free,
   (GCFreeFunc)lj_tab_free,
   (GCFreeFunc)lj_udata_free
   (GCFreeFunc)lj_udata_free
 };
 };

+ 2 - 1
src/lj_ir.h

@@ -316,6 +316,7 @@ typedef enum {
   IRT_PROTO,
   IRT_PROTO,
   IRT_FUNC,
   IRT_FUNC,
   IRT_9,		/* Unused (map of LJ_TTRACE). */
   IRT_9,		/* Unused (map of LJ_TTRACE). */
+  IRT_CDATA,
   IRT_TAB,
   IRT_TAB,
   IRT_UDATA,
   IRT_UDATA,
   /* ... until here. */
   /* ... until here. */
@@ -329,7 +330,7 @@ typedef enum {
   IRT_U8,
   IRT_U8,
   IRT_I16,
   IRT_I16,
   IRT_U16,
   IRT_U16,
-  /* There is room for 14 more types. */
+  /* There is room for 13 more types. */
 
 
   /* Additional flags. */
   /* Additional flags. */
   IRT_MARK = 0x20,	/* Marker for misc. purposes. */
   IRT_MARK = 0x20,	/* Marker for misc. purposes. */

+ 2 - 2
src/lj_obj.c

@@ -11,12 +11,12 @@
 /* Object type names. */
 /* Object type names. */
 LJ_DATADEF const char *const lj_obj_typename[] = {  /* ORDER LUA_T */
 LJ_DATADEF const char *const lj_obj_typename[] = {  /* ORDER LUA_T */
   "no value", "nil", "boolean", "userdata", "number", "string",
   "no value", "nil", "boolean", "userdata", "number", "string",
-  "table", "function", "userdata", "thread", "proto"
+  "table", "function", "userdata", "thread", "proto", "cdata"
 };
 };
 
 
 LJ_DATADEF const char *const lj_obj_itypename[] = {  /* ORDER LJ_T */
 LJ_DATADEF const char *const lj_obj_itypename[] = {  /* ORDER LJ_T */
   "nil", "boolean", "boolean", "userdata", "string", "upval", "thread",
   "nil", "boolean", "boolean", "userdata", "string", "upval", "thread",
-  "proto", "function", "trace", "table", "userdata", "number"
+  "proto", "function", "trace", "cdata", "table", "userdata", "number"
 };
 };
 
 
 /* Compare two objects without calling metamethods. */
 /* Compare two objects without calling metamethods. */

+ 34 - 4
src/lj_obj.h

@@ -165,6 +165,7 @@ typedef const TValue cTValue;
 /* More external and GCobj tags for internal objects. */
 /* More external and GCobj tags for internal objects. */
 #define LAST_TT		LUA_TTHREAD
 #define LAST_TT		LUA_TTHREAD
 #define LUA_TPROTO	(LAST_TT+1)
 #define LUA_TPROTO	(LAST_TT+1)
+#define LUA_TCDATA	(LAST_TT+2)
 
 
 /* Internal object tags.
 /* Internal object tags.
 **
 **
@@ -196,10 +197,11 @@ typedef const TValue cTValue;
 #define LJ_TPROTO		(~7u)
 #define LJ_TPROTO		(~7u)
 #define LJ_TFUNC		(~8u)
 #define LJ_TFUNC		(~8u)
 #define LJ_TTRACE		(~9u)
 #define LJ_TTRACE		(~9u)
-#define LJ_TTAB			(~10u)
-#define LJ_TUDATA		(~11u)
+#define LJ_TCDATA		(~10u)
+#define LJ_TTAB			(~11u)
+#define LJ_TUDATA		(~12u)
 /* This is just the canonical number type used in some places. */
 /* This is just the canonical number type used in some places. */
-#define LJ_TNUMX		(~12u)
+#define LJ_TNUMX		(~13u)
 
 
 #if LJ_64
 #if LJ_64
 #define LJ_TISNUM		0xfffeffffu
 #define LJ_TISNUM		0xfffeffffu
@@ -251,6 +253,28 @@ enum {
 #define uddata(u)	((void *)((u)+1))
 #define uddata(u)	((void *)((u)+1))
 #define sizeudata(u)	(sizeof(struct GCudata)+(u)->len)
 #define sizeudata(u)	(sizeof(struct GCudata)+(u)->len)
 
 
+/* -- C data object ------------------------------------------------------- */
+
+/* C data object. Payload follows. */
+typedef struct GCcdata {
+  GCHeader;
+  uint16_t typeid;	/* C type ID. */
+} GCcdata;
+
+/* Prepended to variable-sized or realigned C data objects. */
+typedef struct GCcdataVar {
+  uint16_t offset;	/* Offset to allocated memory (relative to GCcdata). */
+  uint16_t extra;	/* Extra space allocated (incl. GCcdata + GCcdatav). */
+  MSize len;		/* Size of payload. */
+} GCcdataVar;
+
+#define cdataptr(cd)	((void *)((cd)+1))
+#define cdataisv(cd)	((cd)->marked & 0x80)
+#define cdatav(cd)	((GCcdataVar *)((char *)(cd) - sizeof(GCcdataVar)))
+#define cdatavlen(cd)	check_exp(cdataisv(cd), cdatav(cd)->len)
+#define sizecdatav(cd)	(cdatavlen(cd) + cdatav(cd)->extra)
+#define memcdatav(cd)	((void *)((char *)(cd) - cdatav(cd)->offset))
+
 /* -- Prototype object ---------------------------------------------------- */
 /* -- Prototype object ---------------------------------------------------- */
 
 
 #define SCALE_NUM_GCO	((int32_t)sizeof(lua_Number)/sizeof(GCRef))
 #define SCALE_NUM_GCO	((int32_t)sizeof(lua_Number)/sizeof(GCRef))
@@ -498,6 +522,7 @@ typedef struct global_State {
   BCIns bc_cfunc_ext;	/* Bytecode for external C function calls. */
   BCIns bc_cfunc_ext;	/* Bytecode for external C function calls. */
   GCRef jit_L;		/* Current JIT code lua_State or NULL. */
   GCRef jit_L;		/* Current JIT code lua_State or NULL. */
   MRef jit_base;	/* Current JIT code L->base. */
   MRef jit_base;	/* Current JIT code L->base. */
+  MRef ctype_state;	/* Pointer to C type state. */
   GCRef gcroot[GCROOT_MAX];  /* GC roots. */
   GCRef gcroot[GCROOT_MAX];  /* GC roots. */
 } global_State;
 } global_State;
 
 
@@ -582,6 +607,7 @@ typedef union GCobj {
   lua_State th;
   lua_State th;
   GCproto pt;
   GCproto pt;
   GCfunc fn;
   GCfunc fn;
+  GCcdata cd;
   GCtab tab;
   GCtab tab;
   GCudata ud;
   GCudata ud;
 } GCobj;
 } GCobj;
@@ -592,6 +618,7 @@ typedef union GCobj {
 #define gco2th(o)	check_exp((o)->gch.gct == ~LJ_TTHREAD, &(o)->th)
 #define gco2th(o)	check_exp((o)->gch.gct == ~LJ_TTHREAD, &(o)->th)
 #define gco2pt(o)	check_exp((o)->gch.gct == ~LJ_TPROTO, &(o)->pt)
 #define gco2pt(o)	check_exp((o)->gch.gct == ~LJ_TPROTO, &(o)->pt)
 #define gco2func(o)	check_exp((o)->gch.gct == ~LJ_TFUNC, &(o)->fn)
 #define gco2func(o)	check_exp((o)->gch.gct == ~LJ_TFUNC, &(o)->fn)
+#define gco2cd(o)	check_exp((o)->gch.gct == ~LJ_TCDATA, &(o)->cd)
 #define gco2tab(o)	check_exp((o)->gch.gct == ~LJ_TTAB, &(o)->tab)
 #define gco2tab(o)	check_exp((o)->gch.gct == ~LJ_TTAB, &(o)->tab)
 #define gco2ud(o)	check_exp((o)->gch.gct == ~LJ_TUDATA, &(o)->ud)
 #define gco2ud(o)	check_exp((o)->gch.gct == ~LJ_TUDATA, &(o)->ud)
 
 
@@ -619,6 +646,7 @@ typedef union GCobj {
 #define tvisfunc(o)	(itype(o) == LJ_TFUNC)
 #define tvisfunc(o)	(itype(o) == LJ_TFUNC)
 #define tvisthread(o)	(itype(o) == LJ_TTHREAD)
 #define tvisthread(o)	(itype(o) == LJ_TTHREAD)
 #define tvisproto(o)	(itype(o) == LJ_TPROTO)
 #define tvisproto(o)	(itype(o) == LJ_TPROTO)
+#define tviscdata(o)	(itype(o) == LJ_TCDATA)
 #define tvistab(o)	(itype(o) == LJ_TTAB)
 #define tvistab(o)	(itype(o) == LJ_TTAB)
 #define tvisudata(o)	(itype(o) == LJ_TUDATA)
 #define tvisudata(o)	(itype(o) == LJ_TUDATA)
 #define tvisnum(o)	(itype(o) <= LJ_TISNUM)
 #define tvisnum(o)	(itype(o) <= LJ_TISNUM)
@@ -657,6 +685,7 @@ typedef union GCobj {
 #define funcV(o)	check_exp(tvisfunc(o), &gcval(o)->fn)
 #define funcV(o)	check_exp(tvisfunc(o), &gcval(o)->fn)
 #define threadV(o)	check_exp(tvisthread(o), &gcval(o)->th)
 #define threadV(o)	check_exp(tvisthread(o), &gcval(o)->th)
 #define protoV(o)	check_exp(tvisproto(o), &gcval(o)->pt)
 #define protoV(o)	check_exp(tvisproto(o), &gcval(o)->pt)
+#define cdataV(o)	check_exp(tviscdata(o), &gcval(o)->cd)
 #define tabV(o)		check_exp(tvistab(o), &gcval(o)->tab)
 #define tabV(o)		check_exp(tvistab(o), &gcval(o)->tab)
 #define udataV(o)	check_exp(tvisudata(o), &gcval(o)->ud)
 #define udataV(o)	check_exp(tvisudata(o), &gcval(o)->ud)
 #define numV(o)		check_exp(tvisnum(o), (o)->n)
 #define numV(o)		check_exp(tvisnum(o), (o)->n)
@@ -703,6 +732,7 @@ define_setV(setstrV, GCstr, LJ_TSTR)
 define_setV(setthreadV, lua_State, LJ_TTHREAD)
 define_setV(setthreadV, lua_State, LJ_TTHREAD)
 define_setV(setprotoV, GCproto, LJ_TPROTO)
 define_setV(setprotoV, GCproto, LJ_TPROTO)
 define_setV(setfuncV, GCfunc, LJ_TFUNC)
 define_setV(setfuncV, GCfunc, LJ_TFUNC)
+define_setV(setcdataV, GCcdata, LJ_TCDATA)
 define_setV(settabV, GCtab, LJ_TTAB)
 define_setV(settabV, GCtab, LJ_TTAB)
 define_setV(setudataV, GCudata, LJ_TUDATA)
 define_setV(setudataV, GCudata, LJ_TUDATA)
 
 
@@ -734,7 +764,7 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n)
 /* -- Miscellaneous object handling --------------------------------------- */
 /* -- Miscellaneous object handling --------------------------------------- */
 
 
 /* Names and maps for internal and external object tags. */
 /* Names and maps for internal and external object tags. */
-LJ_DATA const char *const lj_obj_typename[1+LUA_TPROTO+1];
+LJ_DATA const char *const lj_obj_typename[1+LUA_TCDATA+1];
 LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1];
 LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1];
 
 
 #define typename(o)	(lj_obj_itypename[itypemap(o)])
 #define typename(o)	(lj_obj_itypename[itypemap(o)])