aboutsummaryrefslogtreecommitdiffstats
path: root/unmaintained/lua-llthreads/bindings-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'unmaintained/lua-llthreads/bindings-1.patch')
-rw-r--r--unmaintained/lua-llthreads/bindings-1.patch650
1 files changed, 650 insertions, 0 deletions
diff --git a/unmaintained/lua-llthreads/bindings-1.patch b/unmaintained/lua-llthreads/bindings-1.patch
new file mode 100644
index 0000000000..72c116f4fa
--- /dev/null
+++ b/unmaintained/lua-llthreads/bindings-1.patch
@@ -0,0 +1,650 @@
+From dee5a6fabc51c22607fefb5f7a9dd8fe32d098aa Mon Sep 17 00:00:00 2001
+From: "Robert G. Jakabosky" <bobby@sharedrealm.com>
+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 = "<err not a string>";
++ 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 = "<err not a string>";
++ 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["<object_name>"] = 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 = "<err not a string>";
+- 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
+