From 2fd129295555300ac01b17679a6ea4edee2173d2 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Fri, 26 Nov 2010 13:28:46 +0100 Subject: [PATCH] FFI: Add cdata object type. --- lib/dump.lua | 2 ++ src/lib_base.c | 3 ++- src/lj_api.c | 6 ++++-- src/lj_gc.c | 1 + src/lj_ir.h | 3 ++- src/lj_obj.c | 4 ++-- src/lj_obj.h | 38 ++++++++++++++++++++++++++++++++++---- 7 files changed, 47 insertions(+), 10 deletions(-) diff --git a/lib/dump.lua b/lib/dump.lua index 7bee9e79..f567d3d7 100644 --- a/lib/dump.lua +++ b/lib/dump.lua @@ -134,6 +134,7 @@ local irtype_text = { "pro", "fun", "t09", + "cdt", "tab", "udt", "num", @@ -155,6 +156,7 @@ local colortype_ansi = { "%s", "\027[1m%s\027[m", "%s", + "\027[33m%s\027[m", "\027[31m%s\027[m", "\027[36m%s\027[m", "\027[34m%s\027[m", diff --git a/src/lib_base.c b/src/lib_base.c index c7ebafb6..af738008 100644 --- a/src/lib_base.c +++ b/src/lib_base.c @@ -55,8 +55,9 @@ LJLIB_PUSH("thread") LJLIB_PUSH("proto") LJLIB_PUSH("function") LJLIB_PUSH("trace") +LJLIB_PUSH("cdata") LJLIB_PUSH("table") -LJLIB_PUSH(top-8) /* userdata */ +LJLIB_PUSH(top-9) /* userdata */ LJLIB_PUSH("number") LJLIB_ASM_(type) LJLIB_REC(.) /* Recycle the lj_lib_checkany(L, 1) from assert. */ diff --git a/src/lj_api.c b/src/lj_api.c index 827ab42f..b93df344 100644 --- a/src/lj_api.c +++ b/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 */ uint32_t t = ~itype(o); #if LJ_64 - int tt = (int)((U64x(7506,98042110) >> 4*t) & 15u); + int tt = (int)((U64x(75a06,98042110) >> 4*t) & 15u); #else - int tt = (int)(((t < 8 ? 0x98042110 : 0x7506) >> 4*(t&7)) & 15u); + int tt = (int)(((t < 8 ? 0x98042110u : 0x75a06u) >> 4*(t&7)) & 15u); #endif lua_assert(tt != LUA_TNIL || tvisnil(o)); return tt; @@ -525,6 +525,8 @@ LUA_API const void *lua_topointer(lua_State *L, int idx) return uddata(udataV(o)); else if (tvislightud(o)) return lightudV(o); + else if (tviscdata(o)) + return cdataptr(cdataV(o)); else if (tvisgcv(o)) return gcV(o); else diff --git a/src/lj_gc.c b/src/lj_gc.c index 75871a2d..6d47722b 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -373,6 +373,7 @@ static const GCFreeFunc gc_freefunc[] = { #else (GCFreeFunc)0, #endif + (GCFreeFunc)0, /* Placeholder for C data. */ (GCFreeFunc)lj_tab_free, (GCFreeFunc)lj_udata_free }; diff --git a/src/lj_ir.h b/src/lj_ir.h index 8ad5d004..d24d2980 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -316,6 +316,7 @@ typedef enum { IRT_PROTO, IRT_FUNC, IRT_9, /* Unused (map of LJ_TTRACE). */ + IRT_CDATA, IRT_TAB, IRT_UDATA, /* ... until here. */ @@ -329,7 +330,7 @@ typedef enum { IRT_U8, IRT_I16, IRT_U16, - /* There is room for 14 more types. */ + /* There is room for 13 more types. */ /* Additional flags. */ IRT_MARK = 0x20, /* Marker for misc. purposes. */ diff --git a/src/lj_obj.c b/src/lj_obj.c index 3d7e9fcb..5dbed7a8 100644 --- a/src/lj_obj.c +++ b/src/lj_obj.c @@ -11,12 +11,12 @@ /* Object type names. */ LJ_DATADEF const char *const lj_obj_typename[] = { /* ORDER LUA_T */ "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 */ "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. */ diff --git a/src/lj_obj.h b/src/lj_obj.h index cbb25675..83e30b6e 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -165,6 +165,7 @@ typedef const TValue cTValue; /* More external and GCobj tags for internal objects. */ #define LAST_TT LUA_TTHREAD #define LUA_TPROTO (LAST_TT+1) +#define LUA_TCDATA (LAST_TT+2) /* Internal object tags. ** @@ -196,10 +197,11 @@ typedef const TValue cTValue; #define LJ_TPROTO (~7u) #define LJ_TFUNC (~8u) #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. */ -#define LJ_TNUMX (~12u) +#define LJ_TNUMX (~13u) #if LJ_64 #define LJ_TISNUM 0xfffeffffu @@ -251,6 +253,28 @@ enum { #define uddata(u) ((void *)((u)+1)) #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 ---------------------------------------------------- */ #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. */ GCRef jit_L; /* Current JIT code lua_State or NULL. */ MRef jit_base; /* Current JIT code L->base. */ + MRef ctype_state; /* Pointer to C type state. */ GCRef gcroot[GCROOT_MAX]; /* GC roots. */ } global_State; @@ -582,6 +607,7 @@ typedef union GCobj { lua_State th; GCproto pt; GCfunc fn; + GCcdata cd; GCtab tab; GCudata ud; } GCobj; @@ -592,6 +618,7 @@ typedef union GCobj { #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 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 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 tvisthread(o) (itype(o) == LJ_TTHREAD) #define tvisproto(o) (itype(o) == LJ_TPROTO) +#define tviscdata(o) (itype(o) == LJ_TCDATA) #define tvistab(o) (itype(o) == LJ_TTAB) #define tvisudata(o) (itype(o) == LJ_TUDATA) #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 threadV(o) check_exp(tvisthread(o), &gcval(o)->th) #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 udataV(o) check_exp(tvisudata(o), &gcval(o)->ud) #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(setprotoV, GCproto, LJ_TPROTO) define_setV(setfuncV, GCfunc, LJ_TFUNC) +define_setV(setcdataV, GCcdata, LJ_TCDATA) define_setV(settabV, GCtab, LJ_TTAB) define_setV(setudataV, GCudata, LJ_TUDATA) @@ -734,7 +764,7 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n) /* -- Miscellaneous object handling --------------------------------------- */ /* 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]; #define typename(o) (lj_obj_itypename[itypemap(o)])