void dt_lua_register_type_callback_type_typeid(lua_State* L,const char* type_name,lua_CFunction index, lua_CFunction newindex,const char* struct_type_name) { luaL_getmetatable(L,type_name); // gets the metatable since it's supposed to exist luaL_getsubtable(L,-1,"__get"); luaL_getsubtable(L,-2,"__set"); if(!index && !newindex) { index = lautoc_struct_index; newindex = lautoc_struct_newindex; } const char* member = luaA_struct_next_member_name_typeid(L,luaA_type_find(struct_type_name),LUAA_INVALID_MEMBER_NAME); while(member != LUAA_INVALID_MEMBER_NAME) { lua_pushnumber(L,luaA_type_find(struct_type_name)); lua_pushcclosure(L,index,1); lua_setfield(L,-3,member); if(newindex) { lua_pushnumber(L,luaA_type_find(struct_type_name)); lua_pushcclosure(L,newindex,1); lua_setfield(L,-2,member); } member = luaA_struct_next_member_name_typeid(L,luaA_type_find(struct_type_name),member); } lua_pop(L,3); }
void dt_lua_register_type_callback_typeid(lua_State* L,const char* type_name,lua_CFunction index, lua_CFunction newindex,...) { luaL_getmetatable(L,type_name); // gets the metatable since it's supposed to exist luaL_getsubtable(L,-1,"__get"); luaL_getsubtable(L,-2,"__set"); va_list key_list; va_start(key_list,newindex); const char* key = va_arg(key_list,const char*); while(key) { lua_pushcfunction(L,index); lua_setfield(L,-3,key); if(newindex) { lua_pushcfunction(L,newindex); } else { lua_pushnil(L); } lua_setfield(L,-2,key); key = va_arg(key_list,const char*); } va_end(key_list); lua_pop(L,3); }
LUAMOD_API int luaopen_package (lua_State *L) { /* create table CLIBS to keep track of loaded C libraries */ luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); lua_createtable(L, 0, 1); /* metatable for CLIBS */ lua_pushcfunction(L, gctm); lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ lua_setmetatable(L, -2); /* create `package' table */ luaL_newlib(L, pk_funcs); createsearcherstable(L); #if defined(LUA_COMPAT_LOADERS) lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ #endif lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ /* set field 'path' */ setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); /* set field 'cpath' */ setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); /* store config information */ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); lua_setfield(L, -2, "config"); /* set field `loaded' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_setfield(L, -2, "loaded"); /* set field `preload' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_setfield(L, -2, "preload"); lua_pushglobaltable(L); lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ lua_pop(L, 1); /* pop global table */ return 1; /* return 'package' table */ }
void dt_lua_register_type_callback_stack_typeid(lua_State* L,const char* type_name,const char* name) { luaL_getmetatable(L,type_name); // gets the metatable since it's supposed to exist luaL_getsubtable(L,-1,"__get"); luaL_getsubtable(L,-2,"__set"); lua_pushvalue(L,-4); lua_pushcclosure(L,type_const_index,1); lua_setfield(L,-3,name); lua_pop(L,4); }
void dt_lua_type_register_type(lua_State *L, luaA_Type type_id, const char *name) { luaL_getmetatable(L, luaA_typename(L, type_id)); // gets the metatable since it's supposed to exist luaL_getsubtable(L, -1, "__get"); lua_pushvalue(L, -3); lua_setfield(L, -2, name); lua_pop(L, 1); luaL_getsubtable(L, -1, "__set"); lua_pushvalue(L, -3); lua_setfield(L, -2, name); lua_pop(L, 3); }
void CMLuaScript::Unload() { if (status == Loaded) { lua_rawgeti(L, LUA_REGISTRYINDEX, unloadRef); if (lua_isfunction(L, -1)) luaM_pcall(L); lua_pushnil(L); lua_rawsetp(L, LUA_REGISTRYINDEX, this); status = None; } luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_pushnil(L); lua_setfield(L, -2, moduleName); lua_pop(L, 1); KillModuleIcons(id); KillModuleSounds(id); KillModuleMenus(id); KillModuleHotkeys(id); KillObjectEventHooks(this); KillObjectServices(this); }
static void thread_openlibs (lua_State *L, unsigned int loadlibs) { const char *const *libnamep; int i; thread_openlib(L, "_G", luaopen_base); thread_openlib(L, LUA_LOADLIBNAME, luaopen_package); #if LUA_VERSION_NUM < 502 lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); lua_remove(L, -2); #else luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); #endif for (i = 0, libnamep = stdlib_names; *libnamep; ++i, ++libnamep) { const char *name = *libnamep; lua_CFunction func = stdlib_funcs[i]; if ((loadlibs & (1 << i))) thread_openlib(L, name, func); else thread_setfield(L, name, func); } lua_pop(L, 1); /* remove package.preload table */ }
static int int_pushfunc(lua_State *L, luaA_Type type_id, const void *cin) { luaL_getmetatable(L, luaA_typename(L, type_id)); luaL_getsubtable(L, -1, "__values"); int singleton = *(int *)cin; lua_pushnumber(L, singleton); lua_gettable(L, -2); if(lua_isnoneornil(L, -1)) { lua_pop(L, 1); int *udata = lua_newuserdata(L, sizeof(int)); *udata = singleton; luaL_setmetatable(L, luaA_typename(L, type_id)); lua_pushinteger(L, singleton); // warning : no uservalue lua_pushvalue(L, -2); lua_settable(L, -4); if(luaL_getmetafield(L, -1, "__init")) { lua_pushvalue(L, -2); // the new alocated object lua_pushlightuserdata(L, (void *)cin); // forced to cast.. lua_call(L, 2, 0); } } lua_remove(L, -2); //__values lua_remove(L, -2); // metatable return 1; }
static int gpointer_pushfunc(lua_State *L, luaA_Type type_id, const void *cin) { gpointer singleton = *(gpointer *)cin; if(!singleton) { lua_pushnil(L); return 1; } luaL_getsubtable(L, LUA_REGISTRYINDEX, "dt_lua_gpointer_values"); lua_pushlightuserdata(L, singleton); lua_gettable(L, -2); if(lua_isnoneornil(L, -1)) { lua_pop(L, 1); gpointer *udata = lua_newuserdata(L, sizeof(gpointer)); lua_newtable(L); lua_setuservalue(L, -2); *udata = singleton; luaL_setmetatable(L, luaA_typename(L, type_id)); lua_pushlightuserdata(L, singleton); lua_pushvalue(L, -2); lua_settable(L, -4); if(luaL_getmetafield(L, -1, "__init")) { lua_pushvalue(L, -2); // the new alocated object lua_pushlightuserdata(L, (void *)cin); // forced to cast.. lua_call(L, 2, 0); } } lua_remove(L, -2); //dt_lua_gpointer_values return 1; }
int main(int argc, char** argv) { lua_State* L = luaL_newstate(); luaL_openlibs(L); luaL_requiref(L, "sqlite3", luaopen_sqlite3, 1); lua_pop(L, 1); /* remove lib */ /* add open functions from 'preloadedlibs' into 'package.preload' table */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_pushcfunction(L, luaopen_sqlite3); lua_setfield(L, -2, "sqlite3"); lua_pop(L, 1); /* remove _PRELOAD table */ /* luaL_dofile(L, "test.lua"); */ luaL_loadfile(L, "test.lua"); lua_call(L, 0, LUA_MULTRET); lua_close(L); return EXIT_SUCCESS; }
void context_lua_t::lua_init_env(lua_State *L, int32_t envc) { if (envc <= 0) return; const char* path = lua_tostring(L, -envc); const char* cpath = lua_tostring(L, -envc + 1); if (path == NULL && cpath == NULL) { lua_pop(L, envc); return; } lua_checkstack(L, 3); luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, -1, LUA_LOADLIBNAME); /* _LOADED[name] */ if (lua_istable(L, -1)) { if (path) { lua_pushvalue(L, -envc - 2); lua_setfield(L, -2, "path"); } if (cpath) { lua_pushvalue(L, -envc - 1); lua_setfield(L, -2, "cpath"); } } lua_pop(L, envc + 2); return; }
void context_lua_t::lua_load_env(lua_State *L, char* env[]) { lua_checkstack(L, 3); luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, -1, LUA_LOADLIBNAME); /* _LOADED[name] */ if (lua_istable(L, -1)) { char** envp = env; lua_getfield(L, -1, "path"); size_t path_len; const char* lua_path = lua_tolstring(L, -1, &path_len); if (lua_path != NULL && path_len > 0) { char* lua_path_env = (char*)nl_malloc(path_len + 10); strcpy(lua_path_env, "LUA_PATH="); strcpy(lua_path_env + 9, lua_path); *envp++ = lua_path_env; } lua_pop(L, 1); lua_getfield(L, -1, "cpath"); size_t cpath_len; const char* lua_cpath = lua_tolstring(L, -1, &cpath_len); if (lua_cpath != NULL && cpath_len > 0) { char* lua_cpath_env = (char*)nl_malloc(cpath_len + 11); strcpy(lua_cpath_env, "LUA_CPATH="); strcpy(lua_cpath_env + 10, lua_cpath); *envp++ = lua_cpath_env; } lua_pop(L, 3); return; } lua_pop(L, 2); return; }
/* ** create table CLIBS to keep track of loaded C libraries, ** setting a finalizer to close all libraries when closing state. */ static void createclibstable (lua_State *L) { luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */ lua_createtable(L, 0, 1); /* create metatable for CLIBS */ lua_pushcfunction(L, gctm); lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ lua_setmetatable(L, -2); }
inline virtual void get_symbol(state_type state, const std::string& name) override { luaL_getsubtable(state, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(state, -1, name_.c_str()); lua_getfield(state, -1, name.c_str()); lua_remove(state, -2); lua_remove(state, -2); }
LUAMOD_API int luaopen_upackage(lua_State *L) { int i; /* create new type _LOADLIB */ luaL_newmetatable(L, "_LOADLIB"); lua_pushcfunction(L, gctm); lua_setfield(L, -2, "__gc"); /* create `package' table */ luaL_newlib(L, pk_funcs); /* create 'searchers' table */ lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); /* fill it with pre-defined searchers */ for(i=0; searchers[i] != NULL; i++) { lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ lua_pushcclosure(L, searchers[i], 1); lua_rawseti(L, -2, i+1); } #if defined(LUA_COMPAT_LOADERS) lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ #endif lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ /* set field 'path' */ setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); /* set field 'cpath' */ setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); /* store config information */ push_utf8_string(L, LUA_DIRSEP L"\n" LUA_PATH_SEP L"\n" LUA_PATH_MARK L"\n" LUA_EXEC_DIR L"\n" LUA_IGMARK L"\n", -1); lua_setfield(L, -2, "config"); /* set field `loaded' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_setfield(L, -2, "loaded"); /* set field `preload' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); lua_setfield(L, -2, "preload"); lua_pushglobaltable(L); lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ lua_pop(L, 1); /* pop global table */ return 1; /* return 'package' table */ }
static int test_subtable (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); lua_settop(L, 1); if (luaL_getsubtable(L, 1, "xxx")) { lua_pushliteral(L, "oldtable"); } else { lua_pushliteral(L, "newtable"); } return 2; }
inline virtual bool bind(state_type state) override { if(! binded_) { lua_newtable(state); } else { luaL_getsubtable(state, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(state, -1, name_.c_str()); } for(auto& pair : bindables_) { const std::string& name = pair.first; bindable_data& data = pair.second; bindable_ptr_type& bindable = data.bindable; if(!data.status && bindable->bind(state)) { data.status = true; lua_setfield(state, -2, name.c_str()); } } if(!binded_) { luaL_getsubtable(state, LUA_REGISTRYINDEX, "_LOADED"); lua_pushvalue(state, -2); lua_setfield(state, -2, name_.c_str()); lua_pop(state, 1); lua_pushvalue(state, -1); binded_ = true; } else { lua_pop(state, 2); } return true; }
/* ** stripped-down 'require'. Calls 'openf' to open a module, ** registers the result in 'package.loaded' table and, if 'glb' ** is true, also registers the result in the global table. ** Leaves resulting module on the top. */ LUALIB_API void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) { lua_pushcfunction(L, openf); lua_pushstring(L, modname); /* argument to open function */ lua_call(L, 1, 1); /* open module */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_pushvalue(L, -2); /* make copy of module (call result) */ lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ lua_pop(L, 1); /* remove _LOADED table */ if (glb) { lua_pushvalue(L, -1); /* copy of 'mod' */ lua_setglobal(L, modname); /* _G[modname] = module */ } }
bool llib_load(list<string> & libs, lua_State *L, const string &path) { void *handle; lua_CFunction fnc_call; // int (*fnc_call)(lua_State *); char *error; std::string str_lib_name; std::string str_fnc_name; luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); for (list<string>::iterator it = libs.begin(); it != libs.end(); it++) { str_lib_name = path + "/lib" + *it + ".so"; handle = dlopen(str_lib_name.c_str(), RTLD_LOCAL | RTLD_LAZY); if (!handle) { std::cerr << "Error: " << dlerror() << std::endl; return false; } dlerror(); /* Clear any existing error */ str_fnc_name = "luaopen_" + *it; fnc_call = (lua_CFunction) dlsym(handle, str_fnc_name.c_str()); if (fnc_call == NULL) { std::cerr << "Error: Could not load: " << str_fnc_name << std::endl << dlerror() << std::endl; return false; } // luaL_requiref(L, "monitor", &luaopen_monlib, 1); // (*fnc_call)(L); Debug(5) << str_fnc_name; luaL_requiref(L, it->c_str(), fnc_call, 1); lua_pop(L, 1); lua_pushcfunction(L, fnc_call); lua_setfield(L, -2, it->c_str()); dlclose(handle); } // for (list<string>::iterator it = libs.begin(); it != libs.end(); it++) { // // lua_pushcfunction(L, fnc_call); // lua_setfield(L, -2, it->c_str()); // } lua_pop(L, 1); return true; }
LUAMOD_API int luaopen_package (lua_State *L) { createclibstable(L); luaL_newlib(L, pk_funcs); /* create 'package' table */ createsearcherstable(L); /* set paths */ setpath(L, "path", LUA_PATH_VAR, LUA_PATH_DEFAULT); setpath(L, "cpath", LUA_CPATH_VAR, LUA_CPATH_DEFAULT); /* store config information */ lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); lua_setfield(L, -2, "config"); /* set field 'loaded' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE); lua_setfield(L, -2, "loaded"); /* set field 'preload' */ luaL_getsubtable(L, LUA_REGISTRYINDEX, LUA_PRELOAD_TABLE); lua_setfield(L, -2, "preload"); lua_pushglobaltable(L); lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ lua_pop(L, 1); /* pop global table */ return 1; /* return 'package' table */ }
LUALIB_API void luaL_openlibs (lua_State *L) { const luaL_Reg *lib; /* call open functions from 'loadedlibs' and set results to global table */ for (lib = loadedlibs; lib->func; lib++) { luaL_requiref(L, lib->name, lib->func, 1); lua_pop(L, 1); /* remove lib */ } /* add open functions from 'preloadedlibs' into 'package.preload' table */ luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); for (lib = preloadedlibs; lib->func; lib++) { lua_pushcfunction(L, lib->func); lua_setfield(L, -2, lib->name); } lua_pop(L, 1); /* remove _PRELOAD table */ }
void dt_lua_register_type_callback_list_typeid(lua_State* L,const char* type_name,lua_CFunction index, lua_CFunction newindex,const char**list) { luaL_getmetatable(L,type_name); // gets the metatable since it's supposed to exist luaL_getsubtable(L,-1,"__get"); luaL_getsubtable(L,-2,"__set"); const char** key = list; while(*key) { lua_pushcfunction(L,index); lua_setfield(L,-3,*key); if(newindex) { lua_pushcfunction(L,newindex); } else { lua_pushnil(L); } lua_setfield(L,-2,*key); key ++; } lua_pop(L,3); }
int udata_addmethods(lua_State *L, const char* mt, const luaL_Reg* methods) /* Adds methods to the metatable mt */ { if(luaL_getmetatable(L, mt)!=LUA_TTABLE) return luaL_error(L, "cannot find metatable '%s'", mt); if(methods) { /* add methods */ luaL_getsubtable(L, -1, "__index"); luaL_setfuncs(L, methods, 0); lua_pop(L, 1); } lua_pop(L, 1); return 0; }
void dt_lua_type_gpointer_alias_type(lua_State*L,luaA_Type type_id,void* pointer,void* alias) { luaL_getsubtable(L, LUA_REGISTRYINDEX, "dt_lua_gpointer_values"); lua_pushlightuserdata(L, pointer); lua_gettable(L, -2); if(lua_isnoneornil(L, -1)) { luaL_error(L,"Adding an alias to an unknown object for type %s",luaA_typename(L,type_id)); } lua_pushlightuserdata(L,alias); lua_insert(L,-2); lua_settable(L,-3); lua_pop(L,1); }
/* ** stripped-down无装饰的 'require'. Calls 'openf' to open a module, ** registers the result in 'package.loaded' table and, if 'glb' ** is true, also registers the result in the global table. ** Leaves resulting module on the top. ** 没有装饰的"require",调用openf来打开模块,并且注册到package.loaded数组中, ** 如果glb为真,同时注册到全局数组中. */ LUALIB_API void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) { lua_pushcfunction(L, openf); //0x00603ac0 lua_pushstring(L, modname); /* argument to open function */ lua_call(L, 1, 1); /* open module */ //0x00603ad0 //此时openf和modname已经出栈,生成的新table在原来openf处 luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_pushvalue(L, -2); /* make copy of module (call result) */ lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ lua_pop(L, 1); /* remove _LOADED table */ if (glb) { //0x00603ac8 lua_pushvalue(L, -1); /* copy of 'mod' */ //对于多次调用luaL_requiref,全局注册表相应的键值会被最新的覆盖 lua_setglobal(L, modname); /* _G[modname] = module */ } }
int udata_inherit(lua_State *L, const char *sub, const char *super) /* Sets metatable(sub).__index = metatable(super) * * This way, if one accesses a field/method of a 'sub' object which is not defined in * the 'sub' metatable, Lua searches for it in the 'super' metatable (i.e., the 'sub' * type inherits from 'super'). */ { if(luaL_getmetatable(L, sub)!=LUA_TTABLE) return luaL_error(L, "cannot find metatable '%s'", sub); luaL_getsubtable(L, -1, "__index"); if(luaL_getmetatable(L, super)!=LUA_TTABLE) return luaL_error(L, "cannot find metatable '%s'", super); lua_setmetatable(L, -2); lua_pop(L, 2); return 0; }
static int unknown_pushfunc(lua_State *L, luaA_Type type_id, const void *cin) { gpointer singleton = *(gpointer *)cin; if(!singleton) { lua_pushnil(L); return 1; } luaL_getsubtable(L, LUA_REGISTRYINDEX, "dt_lua_gpointer_values"); lua_pushlightuserdata(L, singleton); lua_gettable(L, -2); if(lua_isnoneornil(L, -1)) { return luaL_error(L,"Attempting to push a pointer of unknown type on the stack\n"); } lua_remove(L, -2); //dt_lua_gpointer_values return 1; }
/* ** Stripped-down 'require': After checking "loaded" table, calls 'openf' ** to open a module, registers the result in 'package.loaded' table and, ** if 'glb' is true, also registers the result in the global table. ** Leaves resulting module on the top. */ LUALIB_API void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) { luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, -1, modname); /* _LOADED[modname] */ if (!lua_toboolean(L, -1)) { /* package not already loaded? */ lua_pop(L, 1); /* remove field */ lua_pushcfunction(L, openf); lua_pushstring(L, modname); /* argument to open function */ lua_call(L, 1, 1); /* call 'openf' to open module */ lua_pushvalue(L, -1); /* make copy of module (call result) */ lua_setfield(L, -3, modname); /* _LOADED[modname] = module */ } lua_remove(L, -2); /* remove _LOADED table */ if (glb) { lua_pushvalue(L, -1); /* copy of module */ lua_setglobal(L, modname); /* _G[modname] = module */ } }
void dt_lua_type_gpointer_drop(lua_State*L, void* pointer) { luaL_getsubtable(L, LUA_REGISTRYINDEX, "dt_lua_gpointer_values"); lua_pushlightuserdata(L, pointer); lua_gettable(L,-2); gpointer *udata = (gpointer*)lua_touserdata(L,-1); if(lua_isnil(L,-1)) return; // this table is weak, the object has been gc *udata = NULL; lua_pop(L,1); lua_pushlightuserdata(L, pointer); lua_pushnil(L); lua_settable(L,-3); lua_pop(L,1); }
COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, lua_CFunction openf, int glb) { luaL_checkstack(L, 3, "not enough stack slots available"); luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); if (lua_getfield(L, -1, modname) == LUA_TNIL) { lua_pop(L, 1); lua_pushcfunction(L, openf); lua_pushstring(L, modname); lua_call(L, 1, 1); lua_pushvalue(L, -1); lua_setfield(L, -3, modname); } if (glb) { lua_pushvalue(L, -1); lua_setglobal(L, modname); } lua_replace(L, -2); }