From dee5a6fabc51c22607fefb5f7a9dd8fe32d098aa Mon Sep 17 00:00:00 2001 From: "Robert G. Jakabosky" Date: Mon, 13 Feb 2012 01:47:15 -0800 Subject: [PATCH] Update pre-generated bindings. --- src/pre_generated-llthreads.nobj.c | 378 +++++++++++++++++++++++++++++-------- 1 file changed, 302 insertions(+), 76 deletions(-) diff --git a/src/pre_generated-llthreads.nobj.c b/src/pre_generated-llthreads.nobj.c index 6f53fe5..a7ce73a 100644 --- a/src/pre_generated-llthreads.nobj.c +++ b/src/pre_generated-llthreads.nobj.c @@ -10,13 +10,14 @@ #include "lauxlib.h" #include "lualib.h" - - #define REG_PACKAGE_IS_CONSTRUCTOR 0 +#define REG_MODULES_AS_GLOBALS 0 #define REG_OBJECTS_AS_GLOBALS 0 #define OBJ_DATA_HIDDEN_METATABLE 1 -#define LUAJIT_FFI 0 #define USE_FIELD_GET_SET_METHODS 0 +#define LUAJIT_FFI 0 + + @@ -95,19 +96,26 @@ #define assert_obj_type(type, obj) #endif -#ifndef obj_type_free +void *nobj_realloc(void *ptr, size_t osize, size_t nsize); + +void *nobj_realloc(void *ptr, size_t osize, size_t nsize) { + (void)osize; + if(0 == nsize) { + free(ptr); + return NULL; + } + return realloc(ptr, nsize); +} + #define obj_type_free(type, obj) do { \ assert_obj_type(type, obj); \ - free((obj)); \ + nobj_realloc((obj), sizeof(type), 0); \ } while(0) -#endif -#ifndef obj_type_new #define obj_type_new(type, obj) do { \ assert_obj_type(type, obj); \ - (obj) = malloc(sizeof(type)); \ + (obj) = nobj_realloc(NULL, 0, sizeof(type)); \ } while(0) -#endif typedef struct obj_type obj_type; @@ -165,15 +173,22 @@ struct obj_type { uint32_t flags; /**< is_writable:1bit */ } obj_field; +typedef enum { + REG_OBJECT, + REG_PACKAGE, + REG_META, +} module_reg_type; + typedef struct reg_sub_module { obj_type *type; - int is_package; + module_reg_type req_type; const luaL_reg *pub_funcs; const luaL_reg *methods; const luaL_reg *metas; const obj_base *bases; const obj_field *fields; const obj_const *constants; + int bidirectional_consts; } reg_sub_module; #define OBJ_UDATA_FLAG_OWN (1<<0) @@ -185,18 +200,26 @@ struct obj_type { } obj_udata; /* use static pointer as key to weak userdata table. */ -static char *obj_udata_weak_ref_key = "obj_udata_weak_ref_key"; +static char obj_udata_weak_ref_key[] = "obj_udata_weak_ref_key"; + +/* use static pointer as key to module's private table. */ +static char obj_udata_private_key[] = "obj_udata_private_key"; #if LUAJIT_FFI +typedef int (*ffi_export_func_t)(void); typedef struct ffi_export_symbol { const char *name; - void *sym; + union { + void *data; + ffi_export_func_t func; + } sym; } ffi_export_symbol; #endif + static obj_type obj_types[] = { #define obj_type_id_Lua_LLThread 0 #define obj_type_Lua_LLThread (obj_types[obj_type_id_Lua_LLThread]) @@ -205,10 +228,101 @@ struct obj_type { }; +#if LUAJIT_FFI + +/* nobj_ffi_support_enabled_hint should be set to 1 when FFI support is enabled in at-least one + * instance of a LuaJIT state. It should never be set back to 0. */ +static int nobj_ffi_support_enabled_hint = 0; +static const char nobj_ffi_support_key[] = "LuaNativeObject_FFI_SUPPORT"; +static const char nobj_check_ffi_support_code[] = +"local stat, ffi=pcall(require,\"ffi\")\n" /* try loading LuaJIT`s FFI module. */ +"if not stat then return false end\n" +"return true\n"; + +static int nobj_check_ffi_support(lua_State *L) { + int rc; + int err; + + /* check if ffi test has already been done. */ + lua_pushstring(L, nobj_ffi_support_key); + lua_rawget(L, LUA_REGISTRYINDEX); + if(!lua_isnil(L, -1)) { + rc = lua_toboolean(L, -1); + lua_pop(L, 1); + return rc; /* return results of previous check. */ + } + lua_pop(L, 1); /* pop nil. */ + + err = luaL_loadbuffer(L, nobj_check_ffi_support_code, + sizeof(nobj_check_ffi_support_code) - 1, nobj_ffi_support_key); + if(0 == err) { + err = lua_pcall(L, 0, 1, 0); + } + if(err) { + const char *msg = ""; + if(lua_isstring(L, -1)) { + msg = lua_tostring(L, -1); + } + printf("Error when checking for FFI-support: %s\n", msg); + lua_pop(L, 1); /* pop error message. */ + return 0; + } + /* check results of test. */ + rc = lua_toboolean(L, -1); + lua_pop(L, 1); /* pop results. */ + /* cache results. */ + lua_pushstring(L, nobj_ffi_support_key); + lua_pushboolean(L, rc); + lua_rawset(L, LUA_REGISTRYINDEX); + + /* turn-on hint that there is FFI code enabled. */ + if(rc) { + nobj_ffi_support_enabled_hint = 1; + } + + return rc; +} + +static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name, + const char *ffi_init_code, const ffi_export_symbol *ffi_exports, int priv_table) +{ + int err; + + /* export symbols to priv_table. */ + while(ffi_exports->name != NULL) { + lua_pushstring(L, ffi_exports->name); + lua_pushlightuserdata(L, ffi_exports->sym.data); + lua_settable(L, priv_table); + ffi_exports++; + } + err = luaL_loadbuffer(L, ffi_init_code, strlen(ffi_init_code), ffi_mod_name); + if(0 == err) { + lua_pushvalue(L, -2); /* dup C module's table. */ + lua_pushvalue(L, priv_table); /* move priv_table to top of stack. */ + lua_remove(L, priv_table); + lua_pushvalue(L, LUA_REGISTRYINDEX); + err = lua_pcall(L, 3, 0, 0); + } + if(err) { + const char *msg = ""; + if(lua_isstring(L, -1)) { + msg = lua_tostring(L, -1); + } + printf("Failed to install FFI-based bindings: %s\n", msg); + lua_pop(L, 1); /* pop error message. */ + } + return err; +} +#endif + #ifndef REG_PACKAGE_IS_CONSTRUCTOR #define REG_PACKAGE_IS_CONSTRUCTOR 1 #endif +#ifndef REG_MODULES_AS_GLOBALS +#define REG_MODULES_AS_GLOBALS 0 +#endif + #ifndef REG_OBJECTS_AS_GLOBALS #define REG_OBJECTS_AS_GLOBALS 0 #endif @@ -296,6 +410,25 @@ static FUNC_UNUSED obj_udata *obj_udata_luacheck_internal(lua_State *L, int _ind return ud; } } + } else { + /* handle cdata. */ + /* get private table. */ + lua_pushlightuserdata(L, obj_udata_private_key); + lua_rawget(L, LUA_REGISTRYINDEX); /* private table. */ + /* get cdata type check function from private table. */ + lua_pushlightuserdata(L, type); + lua_rawget(L, -2); + + /* pass cdata value to type checking function. */ + lua_pushvalue(L, _index); + lua_call(L, 1, 1); + if(!lua_isnil(L, -1)) { + /* valid type get pointer from cdata. */ + lua_pop(L, 2); + *obj = *(void **)lua_topointer(L, _index); + return ud; + } + lua_pop(L, 2); } if(not_delete) { luaL_typerror(L, _index, type->name); /* is not a userdata value. */ @@ -309,6 +442,15 @@ static FUNC_UNUSED void *obj_udata_luacheck(lua_State *L, int _index, obj_type * return obj; } +static FUNC_UNUSED void *obj_udata_luaoptional(lua_State *L, int _index, obj_type *type) { + void *obj = NULL; + if(lua_isnil(L, _index)) { + return obj; + } + obj_udata_luacheck_internal(L, _index, &(obj), type, 1); + return obj; +} + static FUNC_UNUSED void *obj_udata_luadelete(lua_State *L, int _index, obj_type *type, int *flags) { void *obj; obj_udata *ud = obj_udata_luacheck_internal(L, _index, &(obj), type, 0); @@ -327,6 +469,17 @@ static FUNC_UNUSED void obj_udata_luapush(lua_State *L, void *obj, obj_type *typ lua_pushnil(L); return; } +#if LUAJIT_FFI + lua_pushlightuserdata(L, type); + lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */ + if(nobj_ffi_support_enabled_hint && lua_isfunction(L, -1)) { + /* call special FFI "void *" to FFI object convertion function. */ + lua_pushlightuserdata(L, obj); + lua_pushinteger(L, flags); + lua_call(L, 2, 1); + return; + } +#endif /* check for type caster. */ if(type->dcaster) { (type->dcaster)(&obj, &type); @@ -336,8 +489,12 @@ static FUNC_UNUSED void obj_udata_luapush(lua_State *L, void *obj, obj_type *typ ud->obj = obj; ud->flags = flags; /* get obj_type metatable. */ +#if LUAJIT_FFI + lua_insert(L, -2); /* move userdata below metatable. */ +#else lua_pushlightuserdata(L, type); lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */ +#endif lua_setmetatable(L, -2); } @@ -383,6 +540,18 @@ static FUNC_UNUSED void obj_udata_luapush_weak(lua_State *L, void *obj, obj_type } lua_pop(L, 1); /* pop nil. */ +#if LUAJIT_FFI + lua_pushlightuserdata(L, type); + lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */ + if(nobj_ffi_support_enabled_hint && lua_isfunction(L, -1)) { + lua_remove(L, -2); + /* call special FFI "void *" to FFI object convertion function. */ + lua_pushlightuserdata(L, obj); + lua_pushinteger(L, flags); + lua_call(L, 2, 1); + return; + } +#endif /* create new userdata. */ ud = (obj_udata *)lua_newuserdata(L, sizeof(obj_udata)); @@ -390,8 +559,12 @@ static FUNC_UNUSED void obj_udata_luapush_weak(lua_State *L, void *obj, obj_type ud->obj = obj; ud->flags = flags; /* get obj_type metatable. */ +#if LUAJIT_FFI + lua_insert(L, -2); /* move userdata below metatable. */ +#else lua_pushlightuserdata(L, type); lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */ +#endif lua_setmetatable(L, -2); /* add weak reference to object. */ @@ -455,15 +628,39 @@ static FUNC_UNUSED void * obj_simple_udata_luacheck(lua_State *L, int _index, ob return ud; } } + } else { + /* handle cdata. */ + /* get private table. */ + lua_pushlightuserdata(L, obj_udata_private_key); + lua_rawget(L, LUA_REGISTRYINDEX); /* private table. */ + /* get cdata type check function from private table. */ + lua_pushlightuserdata(L, type); + lua_rawget(L, -2); + + /* pass cdata value to type checking function. */ + lua_pushvalue(L, _index); + lua_call(L, 1, 1); + if(!lua_isnil(L, -1)) { + /* valid type get pointer from cdata. */ + lua_pop(L, 2); + return (void *)lua_topointer(L, _index); + } + lua_pop(L, 2); } luaL_typerror(L, _index, type->name); /* is not a userdata value. */ return NULL; } -static FUNC_UNUSED void * obj_simple_udata_luadelete(lua_State *L, int _index, obj_type *type, int *flags) { +static FUNC_UNUSED void * obj_simple_udata_luaoptional(lua_State *L, int _index, obj_type *type) { + if(lua_isnil(L, _index)) { + return NULL; + } + return obj_simple_udata_luacheck(L, _index, type); +} + +static FUNC_UNUSED void * obj_simple_udata_luadelete(lua_State *L, int _index, obj_type *type) { void *obj; obj = obj_simple_udata_luacheck(L, _index, type); - *flags = OBJ_UDATA_FLAG_OWN; /* clear the metatable to invalidate userdata. */ lua_pushnil(L); lua_setmetatable(L, _index); @@ -472,12 +669,26 @@ static FUNC_UNUSED void * obj_simple_udata_luadelete(lua_State *L, int _index, o static FUNC_UNUSED void *obj_simple_udata_luapush(lua_State *L, void *obj, int size, obj_type *type) { +#if LUAJIT_FFI + lua_pushlightuserdata(L, type); + lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */ + if(nobj_ffi_support_enabled_hint && lua_isfunction(L, -1)) { + /* call special FFI "void *" to FFI object convertion function. */ + lua_pushlightuserdata(L, obj); + lua_call(L, 1, 1); + return obj; + } +#endif /* create new userdata. */ void *ud = lua_newuserdata(L, size); memcpy(ud, obj, size); /* get obj_type metatable. */ +#if LUAJIT_FFI + lua_insert(L, -2); /* move userdata below metatable. */ +#else lua_pushlightuserdata(L, type); lua_rawget(L, LUA_REGISTRYINDEX); /* type's metatable. */ +#endif lua_setmetatable(L, -2); return ud; @@ -526,7 +737,8 @@ static int obj_constructor_call_wrapper(lua_State *L) { return lua_gettop(L); } -static void obj_type_register_constants(lua_State *L, const obj_const *constants, int tab_idx) { +static void obj_type_register_constants(lua_State *L, const obj_const *constants, int tab_idx, + int bidirectional) { /* register constants. */ while(constants->name != NULL) { lua_pushstring(L, constants->name); @@ -544,6 +756,22 @@ static void obj_type_register_constants(lua_State *L, const obj_const *constants lua_pushnil(L); break; } + /* map values back to keys. */ + if(bidirectional) { + /* check if value already exists. */ + lua_pushvalue(L, -1); + lua_rawget(L, tab_idx - 3); + if(lua_isnil(L, -1)) { + lua_pop(L, 1); + /* add value->key mapping. */ + lua_pushvalue(L, -1); + lua_pushvalue(L, -3); + lua_rawset(L, tab_idx - 4); + } else { + /* value already exists. */ + lua_pop(L, 1); + } + } lua_rawset(L, tab_idx - 2); constants++; } @@ -558,20 +786,48 @@ static void obj_type_register_package(lua_State *L, const reg_sub_module *type_r luaL_register(L, NULL, reg_list); } - obj_type_register_constants(L, type_reg->constants, -1); + obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts); lua_pop(L, 1); /* drop package table */ } +static void obj_type_register_meta(lua_State *L, const reg_sub_module *type_reg) { + const luaL_reg *reg_list; + + /* create public functions table. */ + reg_list = type_reg->pub_funcs; + if(reg_list != NULL && reg_list[0].name != NULL) { + /* register functions */ + luaL_register(L, NULL, reg_list); + } + + obj_type_register_constants(L, type_reg->constants, -1, type_reg->bidirectional_consts); + + /* register methods. */ + luaL_register(L, NULL, type_reg->methods); + + /* create metatable table. */ + lua_newtable(L); + luaL_register(L, NULL, type_reg->metas); /* fill metatable */ + /* setmetatable on meta-object. */ + lua_setmetatable(L, -2); + + lua_pop(L, 1); /* drop meta-object */ +} + static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int priv_table) { const luaL_reg *reg_list; obj_type *type = type_reg->type; const obj_base *base = type_reg->bases; - if(type_reg->is_package == 1) { + if(type_reg->req_type == REG_PACKAGE) { obj_type_register_package(L, type_reg); return; } + if(type_reg->req_type == REG_META) { + obj_type_register_meta(L, type_reg); + return; + } /* create public functions table. */ reg_list = type_reg->pub_funcs; @@ -620,14 +876,10 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int lua_pushvalue(L, -2); /* dup metatable. */ lua_rawset(L, LUA_REGISTRYINDEX); /* REGISTRY[type] = metatable */ -#if LUAJIT_FFI /* add metatable to 'priv_table' */ lua_pushstring(L, type->name); lua_pushvalue(L, -2); /* dup metatable. */ lua_rawset(L, priv_table); /* priv_table[""] = metatable */ -#else - (void)priv_table; -#endif luaL_register(L, NULL, type_reg->metas); /* fill metatable */ @@ -638,7 +890,7 @@ static void obj_type_register(lua_State *L, const reg_sub_module *type_reg, int base++; } - obj_type_register_constants(L, type_reg->constants, -2); + obj_type_register_constants(L, type_reg->constants, -2, type_reg->bidirectional_consts); lua_pushliteral(L, "__index"); lua_pushvalue(L, -3); /* dup methods table */ @@ -658,54 +910,12 @@ static FUNC_UNUSED int lua_checktype_ref(lua_State *L, int _index, int _type) { return luaL_ref(L, LUA_REGISTRYINDEX); } -#if LUAJIT_FFI -static int nobj_udata_new_ffi(lua_State *L) { - size_t size = luaL_checkinteger(L, 1); - luaL_checktype(L, 2, LUA_TTABLE); - lua_settop(L, 2); - /* create userdata. */ - lua_newuserdata(L, size); - lua_replace(L, 1); - /* set userdata's metatable. */ - lua_setmetatable(L, 1); - return 1; -} - -static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name, - const char *ffi_init_code, const ffi_export_symbol *ffi_exports, int priv_table) -{ - int err; - - /* export symbols to priv_table. */ - while(ffi_exports->name != NULL) { - lua_pushstring(L, ffi_exports->name); - lua_pushlightuserdata(L, ffi_exports->sym); - lua_settable(L, priv_table); - ffi_exports++; - } - err = luaL_loadbuffer(L, ffi_init_code, strlen(ffi_init_code), ffi_mod_name); - if(0 == err) { - lua_pushvalue(L, -2); /* dup C module's table. */ - lua_pushvalue(L, priv_table); /* move priv_table to top of stack. */ - lua_remove(L, priv_table); - lua_pushcfunction(L, nobj_udata_new_ffi); - err = lua_pcall(L, 3, 0, 0); - } - if(err) { - const char *msg = ""; - if(lua_isstring(L, -1)) { - msg = lua_tostring(L, -1); - } - printf("Failed to install FFI-based bindings: %s\n", msg); - lua_pop(L, 1); /* pop error message. */ - } - return err; -} -#endif #define obj_type_Lua_LLThread_check(L, _index) \ obj_udata_luacheck(L, _index, &(obj_type_Lua_LLThread)) +#define obj_type_Lua_LLThread_optional(L, _index) \ + obj_udata_luaoptional(L, _index, &(obj_type_Lua_LLThread)) #define obj_type_Lua_LLThread_delete(L, _index, flags) \ obj_udata_luadelete_weak(L, _index, &(obj_type_Lua_LLThread), flags) #define obj_type_Lua_LLThread_push(L, obj, flags) \ @@ -714,8 +924,6 @@ static int nobj_try_loading_ffi(lua_State *L, const char *ffi_mod_name, - - /* maximum recursive depth of table copies. */ #define MAX_COPY_DEPTH 30 @@ -1106,7 +1314,7 @@ static Lua_LLThread *llthread_create(lua_State *L, const char *code, size_t code -/* method: delete */ +/* method: _priv */ static int Lua_LLThread__delete__meth(lua_State *L) { int this_flags_idx1 = 0; Lua_LLThread * this_idx1 = obj_type_Lua_LLThread_delete(L,1,&(this_flags_idx1)); @@ -1264,14 +1472,21 @@ static int llthreads__new__func(lua_State *L) { static const reg_sub_module reg_sub_modules[] = { - { &(obj_type_Lua_LLThread), 0, obj_Lua_LLThread_pub_funcs, obj_Lua_LLThread_methods, obj_Lua_LLThread_metas, obj_Lua_LLThread_bases, obj_Lua_LLThread_fields, obj_Lua_LLThread_constants}, - {NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL} + { &(obj_type_Lua_LLThread), REG_OBJECT, obj_Lua_LLThread_pub_funcs, obj_Lua_LLThread_methods, obj_Lua_LLThread_metas, obj_Lua_LLThread_bases, obj_Lua_LLThread_fields, obj_Lua_LLThread_constants, 0}, + {NULL, 0, NULL, NULL, NULL, NULL, NULL, NULL, 0} }; +#if LUAJIT_FFI +static const ffi_export_symbol llthreads_ffi_export[] = { + {NULL, { .data = NULL } } +}; +#endif + + static const luaL_Reg submodule_libs[] = { @@ -1304,20 +1519,26 @@ LUA_NOBJ_API int luaopen_llthreads(lua_State *L) { const luaL_Reg *submodules = submodule_libs; int priv_table = -1; -#if LUAJIT_FFI /* private table to hold reference to object metatables. */ lua_newtable(L); priv_table = lua_gettop(L); -#endif + lua_pushlightuserdata(L, obj_udata_private_key); + lua_pushvalue(L, priv_table); + lua_rawset(L, LUA_REGISTRYINDEX); /* store private table in registry. */ /* create object cache. */ create_object_instance_cache(L); /* module table. */ +#if REG_MODULES_AS_GLOBALS luaL_register(L, "llthreads", llthreads_function); +#else + lua_newtable(L); + luaL_register(L, NULL, llthreads_function); +#endif /* register module constants. */ - obj_type_register_constants(L, llthreads_constants, -1); + obj_type_register_constants(L, llthreads_constants, -1, 0); for(; submodules->func != NULL ; submodules++) { lua_pushcfunction(L, submodules->func); @@ -1338,9 +1559,14 @@ LUA_NOBJ_API int luaopen_llthreads(lua_State *L) { } #if LUAJIT_FFI - nobj_try_loading_ffi(L, "llthreads", llthreads_ffi_lua_code, - llthreads_ffi_export, priv_table); + if(nobj_check_ffi_support(L)) { + nobj_try_loading_ffi(L, "llthreads", llthreads_ffi_lua_code, + llthreads_ffi_export, priv_table); + } #endif + + + return 1; } -- 1.8.1.6