static void compat53_call_lua (lua_State *L, char const code[], size_t len, int nargs, int nret) { lua_rawgetp(L, LUA_REGISTRYINDEX, (void*)code); if (lua_type(L, -1) != LUA_TFUNCTION) { lua_pop(L, 1); if (luaL_loadbuffer(L, code, len, "=none")) lua_error(L); lua_pushvalue(L, -1); lua_rawsetp(L, LUA_REGISTRYINDEX, (void*)code); } lua_insert(L, -nargs-1); lua_call(L, nargs, nret); }
static void create_if_not_exits(lua_State *L) { if (LUA_TTABLE == lua_rawgetp(L, LUA_REGISTRYINDEX, &CLIBS)) { return; } lua_pop(L, 1); lua_newtable(L); lua_createtable(L, 0, 1); lua_pushcfunction(L, mt_gc); lua_setfield(L, -2, "__gc"); lua_setmetatable(L, -2); lua_pushvalue(L, -1); lua_rawsetp(L, LUA_REGISTRYINDEX, &CLIBS); }
static int _cb(struct skynet_context * context, void * ud, int session, const char * addr, const void * msg, size_t sz) { lua_State *L = ud; int trace = 1; int top = lua_gettop(L); if (top == 1) { lua_rawgetp(L, LUA_REGISTRYINDEX, _cb); } else { assert(top == 2); lua_pushvalue(L,2); } int r; if (msg == NULL) { if (addr == NULL) { lua_pushinteger(L, session); r = lua_pcall(L, 1, 0 , trace); } else { lua_pushinteger(L, session); lua_pushstring(L, addr); r = lua_pcall(L, 2, 0 , trace); } } else { lua_pushinteger(L, session); lua_pushstring(L, addr); lua_pushlightuserdata(L,(void *)msg); lua_pushinteger(L,sz); r = lua_pcall(L, 4, 0 , trace); } if (r == LUA_OK) return 0; const char * self = skynet_command(context, "REG", NULL); switch (r) { case LUA_ERRRUN: skynet_error(context, "lua call [%s to %s : %d msgsz = %d] error : %s", addr , self, session, sz, lua_tostring(L,-1)); break; case LUA_ERRMEM: skynet_error(context, "lua memory error : [%s to %s : %d]", addr , self, session); break; case LUA_ERRERR: skynet_error(context, "lua error in error : [%s to %s : %d]", addr , self, session); break; case LUA_ERRGCMM: skynet_error(context, "lua gc error : [%s to %s : %d]", addr , self, session); break; }; lua_pop(L,1); return 0; }
/* ** Call hook function registered at hook table for the current ** thread (if there is one) */ static void hookf (lua_State *L, lua_Debug *ar) { static const char *const hooknames[] = {"call", "return", "line", "count", "tail call"}; lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); lua_pushthread(L); if (lua_rawget(L, -2) == LUA_TFUNCTION) { /* is there a hook function? */ lua_pushstring(L, hooknames[(int)ar->event]); /* push event name */ if (ar->currentline >= 0) lua_pushinteger(L, ar->currentline); /* push current line */ else lua_pushnil(L); lua_assert(lua_getinfo(L, "lS", ar)); lua_call(L, 2, 0); /* call hook function */ } }
static void hookf (lua_State *L, lua_Debug *ar) { static const char *const hooknames[] = {"call", "return", "line", "count", "tail call"}; gethooktable(L); lua_rawgetp(L, -1, L); if (lua_isfunction(L, -1)) { lua_pushstring(L, hooknames[(int)ar->event]); if (ar->currentline >= 0) lua_pushinteger(L, ar->currentline); else lua_pushnil(L); lua_assert(lua_getinfo(L, "lS", ar)); lua_call(L, 2, 0); } }
static int type_exists(lua_State *L, const lbind_Type *t) { lua_rawgetp(L, LUA_REGISTRYINDEX, (const void*)t); if (!lua_isnil(L, -1)) { lua_pop(L, 1); return 1; } lua_getfield(L, LUA_REGISTRYINDEX, t->name); if (!lua_isnil(L, -1)) { lua_pop(L, 1); return 1; } lua_pop(L, 2); return 0; }
void LuaInterface::lookupMethod(void *o, const char *func) { int lty = lua_rawgetp(_lua, LUA_REGISTRYINDEX, o); #ifdef _DEBUG assert(lty == LUA_TUSERDATA); #endif // now [Lglue] lty = lua_getfield(_lua, -1, func); #ifdef _DEBUG assert(lty == LUA_TFUNCTION); #endif // now [Lglue][func] lua_insert(_lua, -2); // now [func][Lglue] }
static int hookC2lua(lua_State* L) { luaL_checktype(L, 1, LUA_TSTRING); luaL_checktype(L, 2, LUA_TNUMBER); lua_rawgetp(L, lua_upvalueindex(1), &FFI_NEW); if (lua_type(L, -1) != LUA_TFUNCTION) { return luaL_error(L, "No initialization."); } uintptr_t fp = (uintptr_t)luaL_checkinteger(L, 2); lua_pushvalue(L, 1); lua_pushnil(L); lua_call(L, 2, 1); uintptr_t cd = (uintptr_t)lua_touserdata(L, -1); *(uintptr_t*)(cd + 16) = fp; return 1; }
static int luaopen_lcurl_(lua_State *L, const struct luaL_Reg *func){ if(!LCURL_INIT){ curl_global_init(CURL_GLOBAL_DEFAULT); LCURL_INIT = 1; } lua_rawgetp(L, LUA_REGISTRYINDEX, LCURL_REGISTRY); if(!lua_istable(L, -1)){ /* registry */ lua_pop(L, 1); lua_newtable(L); } lua_rawgetp(L, LUA_REGISTRYINDEX, LCURL_USERVAL); if(!lua_istable(L, -1)){ /* usevalues */ lua_pop(L, 1); lcurl_util_new_weak_table(L, "k"); } lua_newtable(L); /* library */ lua_pushvalue(L, -3); lua_pushvalue(L, -3); luaL_setfuncs(L, func, 2); lua_pushvalue(L, -3); lua_pushvalue(L, -3); lcurl_error_initlib(L, 2); lua_pushvalue(L, -3); lua_pushvalue(L, -3); lcurl_hpost_initlib(L, 2); lua_pushvalue(L, -3); lua_pushvalue(L, -3); lcurl_easy_initlib (L, 2); lua_pushvalue(L, -3); lua_pushvalue(L, -3); lcurl_multi_initlib(L, 2); lua_pushvalue(L, -3); lua_pushvalue(L, -3); lcurl_share_initlib(L, 2); lua_pushvalue(L, -3); lua_rawsetp(L, LUA_REGISTRYINDEX, LCURL_REGISTRY); lua_pushvalue(L, -2); lua_rawsetp(L, LUA_REGISTRYINDEX, LCURL_USERVAL); lua_remove(L, -2); /* registry */ lcurl_util_set_const(L, lcurl_flags); return 1; }
/* * Arguments: ecb_udata, {string | membuf_udata} ... * Returns: [success/partial (boolean), count (number)] */ static int ecb_write (lua_State *L) { LPEXTENSION_CONTROL_BLOCK ecb = lua_unboxpointer(L, 1, ECB_TYPENAME); size_t n = 0; /* number of chars actually write */ int i, narg = lua_gettop(L); if (ecb->dwHttpStatusCode & ECB_STATUS_HEADERS_SEND) { ecb->dwHttpStatusCode ^= ECB_STATUS_HEADERS_SEND; lua_pushfstring(L, "HTTP/1.1 %d\r\n", (ecb->dwHttpStatusCode & ECB_STATUS_MASK)); lua_rawgetp(L, LUA_REGISTRYINDEX, ecb); lua_pushliteral(L, "\r\n"); lua_concat(L, 3); lua_insert(L, 2); ++narg; } for (i = 2; i <= narg; ++i) { struct sys_buffer sb; int nw; if (!sys_buffer_read_init(L, i, &sb) || sb.size == 0) /* don't close the connection */ continue; sys_vm_leave(); { DWORD l = sb.size; nw = ecb->WriteClient(ecb->ConnID, sb.ptr.w, &l, 0) ? (int) l : -1; } sys_vm_enter(); if (nw == -1) { if (n > 0) break; return sys_seterror(L, 0); } n += nw; sys_buffer_read_next(&sb, nw); if ((size_t) nw < sb.size) break; } lua_pushboolean(L, (i > narg)); lua_pushinteger(L, n); return 2; }
static int luaopen_lluv_impl(lua_State *L, int safe){ #define NUPVALUES 2 #define LLUV_PUSH_UPVALUES(L) lua_pushvalue(L, -3); lua_pushvalue(L, -3) lua_rawgetp(L, LUA_REGISTRYINDEX, LLUV_REGISTRY); if(!lua_istable(L, -1)){ /* registry */ lua_pop(L, 1); lua_newtable(L); lua_pushvalue(L, -1); lua_rawsetp(L, LUA_REGISTRYINDEX, LLUV_REGISTRY); lluv_new_weak_table(L, "kv");lua_pushvalue(L, -1); lua_rawsetp(L, LUA_REGISTRYINDEX, LLUV_HANDLES); } lua_newtable(L); /* registry, handles, library */ LLUV_PUSH_UPVALUES(L); lluv_loop_initlib (L, NUPVALUES); LLUV_PUSH_UPVALUES(L); luaL_setfuncs(L, lluv_functions, NUPVALUES); LLUV_PUSH_UPVALUES(L); lluv_error_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_fs_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_handle_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_stream_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_timer_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_fbuf_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_idle_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_tcp_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_pipe_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_tty_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_udp_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_prepare_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_check_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_poll_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_signal_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_fs_event_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_fs_poll_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_process_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_misc_initlib (L, NUPVALUES, safe); LLUV_PUSH_UPVALUES(L); lluv_dns_initlib (L, NUPVALUES, safe); lua_remove(L, -2); /* registry */ lua_remove(L, -2); /* handles */ lluv_push_version(L); lua_setfield(L, -2, "_VERSION"); return 1; #undef LLUV_PUSH_UPVALUES #undef NUPVALUES }
bool NativeTypeBase::checkBridgeTable(lua_State *L, MemberInfo *info, void *ptr, const char *key) { if (info->getDeclaringType()->isPrimitive() && !info->isStatic()) { return true; } int top = lua_gettop(L); lua_rawgetp(L, LUA_REGISTRYINDEX, ptr); assert(lua_istable(L, -1)); lua_getmetatable(L, -1); lua_pushstring(L, key); lua_rawget(L, -2); if (!lua_isnil(L, -1)) { lua_rawseti(L, -2, info->getOrdinal()); lua_settop(L, top); return true; } lua_pop(L, 1); lua_rawgeti(L, -1, LSINDEXBRIDGE_PROPGET); lua_pushstring(L, key); lua_rawget(L, -2); // store via native ordinal as well for fast lookup bool ret = !lua_isnil(L, -1); lua_rawseti(L, -2, info->getOrdinal()); lua_pop(L, 1); lua_rawgeti(L, -1, LSINDEXBRIDGE_PROPSET); lua_pushstring(L, key); lua_rawget(L, -2); // store via native ordinal as well for fast lookup lua_rawseti(L, -2, info->getOrdinal()); lua_settop(L, top); return ret; }
void lualoom_newnativeuserdata(lua_State *L, NativeTypeBase *nativeType, void *p) { new (lua_newuserdata(L, sizeof(Detail::UserdataPtr))) Detail::UserdataPtr(p); Detail::Userdata *ud = (Detail::Userdata *)lua_topointer(L, -1); // set the user data's native type ud->m_nativeType = nativeType; // look up the classes meta table by bridge key lua_rawgetp(L, LUA_REGISTRYINDEX, nativeType->getBridgeClassKey()); // If this goes off it means you forgot to register the class! lmAssert(lua_istable(L, -1), "unable to retrieve metatable for native class %s", nativeType->getCTypeName().c_str()); lua_setmetatable(L, -2); }
struct cell * cell_fromuserdata(lua_State *L, int index) { if (lua_type(L, index) != LUA_TUSERDATA) { return NULL; } if (lua_getmetatable(L, index)) { lua_rawgetp(L, -1 , CELL_TAG); if (lua_toboolean(L, -1)) { lua_pop(L,2); struct cell_ud * cud = lua_touserdata(L, index); return cud->c; } lua_pop(L,2); } return NULL; }
static int db_gethook (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); char buff[5]; int mask = lua_gethookmask(L1); lua_Hook hook = lua_gethook(L1); if (hook != NULL && hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { gethooktable(L); lua_rawgetp(L, -1, L1); /* get hook */ lua_remove(L, -2); /* remove hook table */ } lua_pushstring(L, unmakemask(mask, buff)); lua_pushinteger(L, lua_gethookcount(L1)); return 3; }
//{ logger interface void llthread_log(lua_State *L, const char *hdr, const char *msg){ int top = lua_gettop(L); lua_rawgetp(L, LUA_REGISTRYINDEX, LLTHREAD_LOGGER_HOLDER); if(lua_isnil(L, -1)){ lua_pop(L, 1); fputs(hdr, stderr); fputs(msg, stderr); fputc('\n', stderr); fflush(stderr); return; } lua_pushstring(L, hdr); lua_pushstring(L, msg); lua_concat(L, 2); lua_pcall(L, 1, 0, 0); lua_settop(L, top); }
static lbind_Object *testobj(lua_State *L, int idx) { lbind_Object *obj = (lbind_Object*)lua_touserdata(L, idx); if (obj != NULL) { if (!check_size(L, idx) || obj->o.instance == NULL) obj = NULL; #if 0 else { get_internbox(L); /* 1 */ lua_rawgetp(L, -1, obj->o.instance); /* 2 */ if (!lua_rawequal(L, lbind_relindex(idx, 2), -1)) obj = NULL; lua_pop(L, 2); /* (2)(1) */ } #endif } return obj; }
static struct vars * argvars(lua_State *L, int onlyfetch) { static int args = 0; if (onlyfetch) { lua_rawgetp(L, LUA_REGISTRYINDEX, &args); if (lua_isuserdata(L, -1)) { struct vars ** box = (struct vars **)lua_touserdata(L, -1); lua_pop(L,1); return *box; } else { lua_pop(L,1); return NULL; } } else { return getvars(L, &args); } }
static int _cb(struct skynet_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { lua_State *L = ud; int trace = 1; int r; int top = lua_gettop(L); if (top == 0) { lua_pushcfunction(L, traceback); lua_rawgetp(L, LUA_REGISTRYINDEX, _cb); } else { assert(top == 2); } lua_pushvalue(L,2); lua_pushinteger(L, type); lua_pushlightuserdata(L, (void *)msg); lua_pushinteger(L,sz); lua_pushinteger(L, session); lua_pushnumber(L, source); r = lua_pcall(L, 5, 0 , trace); if (r == LUA_OK) { return 0; } const char * self = skynet_command(context, "REG", NULL); switch (r) { case LUA_ERRRUN: skynet_error(context, "lua call [%x to %s : %d msgsz = %d] error : " KRED "%s" KNRM, source , self, session, sz, lua_tostring(L,-1)); break; case LUA_ERRMEM: skynet_error(context, "lua memory error : [%x to %s : %d]", source , self, session); break; case LUA_ERRERR: skynet_error(context, "lua error in error : [%x to %s : %d]", source , self, session); break; case LUA_ERRGCMM: skynet_error(context, "lua gc error : [%x to %s : %d]", source , self, session); break; }; lua_pop(L,1); return 0; }
//处理消息回调 static int _cb(struct server_context * context, void * ud, int type, int session, uint32_t source, const void * msg, size_t sz) { lua_State *L = ud; int trace = 1; int r; int top = lua_gettop(L); if (top == 0) { lua_pushcfunction(L, traceback); lua_rawgetp(L, LUA_REGISTRYINDEX, _cb); } else { assert(top == 2); } lua_pushvalue(L,2);//拷贝cb放到栈顶,用于执行,那么栈底就存放着 traceback, _cb lua_pushinteger(L, type); lua_pushlightuserdata(L, (void *)msg); lua_pushinteger(L,sz); lua_pushinteger(L, session); lua_pushnumber(L, source); r = lua_pcall(L, 5, 0 , trace); if (r == LUA_OK) {//运行成功 return 0; } const char * self = server_cmd_command(context, "REG", NULL); switch (r) { case LUA_ERRRUN://运行时错误 server_error(context, "lua call [%x to %s : %d msgsz = %d] error : " KRED "%s" KNRM, source , self, session, sz, lua_tostring(L,-1)); break; case LUA_ERRMEM://内存分配错误。对于这种错,Lua不会调用错误处理函数 server_error(context, "lua memory error : [%x to %s : %d]", source , self, session); break; case LUA_ERRERR://在运行错误处理函数时发生的错误 server_error(context, "lua error in error : [%x to %s : %d]", source , self, session); break; case LUA_ERRGCMM://在运行 __gc 元方法时发生的错误(这个错误和被调用的函数无关) server_error(context, "lua gc error : [%x to %s : %d]", source , self, session); break; }; lua_pop(L,1);//从栈顶弹出1个元素,即弹出错误信息 return 0; }
static struct vars * getvars(lua_State *L, void *p) { struct vars *args = NULL; lua_rawgetp(L, LUA_REGISTRYINDEX, p); if (lua_isuserdata(L, -1)) { struct vars ** box = (struct vars **)lua_touserdata(L, -1); args = *box; lua_pop(L,1); } else { lua_pop(L,1); args = newvarsobject(L); if (args == NULL) luaL_error(L, "new result object failed"); lua_rawsetp(L, LUA_REGISTRYINDEX, p); } lbind_clear(args); return args; }
LDBUS_INTERNAL void ldbus_timeout_toggled_function(DBusTimeout *timeout, void *data) { lua_State *L = ((ldbus_timeout_udata*)data)->L; int ref = ((ldbus_timeout_udata*)data)->ref; /* Lookup remove callback from ref in `data` */ lua_rawgeti(L, LUA_REGISTRYINDEX, ref); lua_rawgeti(L, -1, DBUS_LUA_FUNC_TOGGLE); /* Remove callback table from stack */ lua_remove(L, lua_gettop(L)-1); /* Grab timeout from registry */ /* this way we can't throw an error */ lua_rawgetp(L, LUA_REGISTRYINDEX, timeout); /* Call the callback, with looked-up timeout as argument */ lua_pcall(L, 1, 0, 0); return; }
void sys_thread_check (struct sys_thread *td, lua_State *L) { lua_assert(td); { const unsigned int flags = td->flags; if (flags == SYS_THREAD_TERMINATE) { td->flags = SYS_THREAD_KILLED; thread_exit(td); } else if (flags == SYS_THREAD_INTERRUPT) { lua_rawgetp(L, LUA_REGISTRYINDEX, THREAD_KEY_ADDRESS); lua_rawgeti(L, -1, THREAD_TABLE_EINTR); lua_error(L); } } }
static void _cb(struct skynet_context * context, void * ud, int session, const char * addr, const void * msg, size_t sz) { lua_State *L = ud; lua_pushcfunction(L, traceback); lua_rawgetp(L, LUA_REGISTRYINDEX, _cb); int r; if (msg == NULL) { lua_pushinteger(L, session); r = lua_pcall(L, 1, 0 , -3); } else { lua_pushinteger(L, session); lua_pushstring(L, addr); lua_pushlstring(L, msg, sz); r = lua_pcall(L, 3, 0 , -5); } if (r == LUA_OK) return; skynet_error(context, "lua error %s", lua_tostring(L,-1)); }
static int lselect(lua_State *L) { lua_rawgetp(L, LUA_REGISTRYINDEX, S); if (lua_type(L, -1) != LUA_TNUMBER) return luaL_error(L, "select should call in a task"); taskid id = lua_tointeger(L, -1); lua_pop(L, 1); int n = lua_gettop(L); channelid channels[n]; int i; for (i=0;i<n;i++) { channels[i] = luaL_checkinteger(L, i+1); } channelid c = schedule_select(S, id, n, channels); if (c == 0) return 0; lua_pushinteger(L, c); return 1; }
static const void * readobject(lua_State *L, lua_State *dL, const void *parent, const char *desc) { int t = lua_type(L, -1); int tidx = 0; const void * p = NULL; switch (t) { case LUA_TTABLE: tidx = TABLE; break; case LUA_TFUNCTION: tidx = FUNCTION; break; case LUA_TTHREAD: tidx = THREAD; break; case LUA_TUSERDATA: tidx = USERDATA; break; default: return NULL; } p = lua_topointer(L, -1); if (ismarked(dL, p)) { lua_rawgetp(dL, tidx, p); if (!lua_isnil(dL,-1)) { lua_pushstring(dL,desc); lua_rawsetp(dL, -2, parent); } lua_pop(dL,1); lua_pop(L,1); return NULL; } lua_newtable(dL); lua_pushstring(dL,desc); lua_rawsetp(dL, -2, parent); lua_rawsetp(dL, tidx, p); return p; }
static int db_gethook (lua_State *L) { int arg; lua_State *L1 = getthread(L, &arg); char buff[5]; int mask = lua_gethookmask(L1); lua_Hook hook = lua_gethook(L1); if (hook == NULL) /* no hook? */ lua_pushnil(L); else if (hook != hookf) /* external hook? */ lua_pushliteral(L, "external hook"); else { /* hook table must exist */ lua_rawgetp(L, LUA_REGISTRYINDEX, &HOOKKEY); lua_pushthread(L1); lua_xmove(L1, L, 1); lua_rawget(L, -2); /* 1st result = hooktable[L1] */ lua_remove(L, -2); /* remove hook table */ } lua_pushstring(L, unmakemask(mask, buff)); /* 2nd result = mask */ lua_pushinteger(L, lua_gethookcount(L1)); /* 3rd result = count */ return 3; }
void LuaValue::setTable() { if (bool(data_)==false) { return; } auto ls__=data_->luaState_.lock(); if (bool(ls__)==false) { return; } lua_State * L=ls__.get(); __cct::__private::TopLock _lock_(L); if (lua_istable(L,-1)) { const int value_pos_=lua_gettop(L); _setValue<Type_Table>(L); lua_rawgetp(L,LUA_REGISTRYINDEX,getTablePathPointer(Type_Table)); if (lua_istable(L,-1)==false) { lua_pop(L,1); lua_newtable(L); lua_pushvalue(L,-1); lua_rawsetp(L,LUA_REGISTRYINDEX,getTablePathPointer(Type_Table)); } lua_pushvalue(L,value_pos_); lua_rawseti(L,-2,data_->pointer_); } }
/*-------------------------------------------------------------------------*\ * Error wrapper \*-------------------------------------------------------------------------*/ static int try_check_error(lua_State *L) { if(lua_istable(L, -1)){ lua_rawgetp(L, -1, TRY_ERROR_NIL); if(lua_isnil(L, -1)){ /*not try error*/ lua_pop(L, 1); return 0; } if(lua_touserdata(L, -1) == TRY_ERROR_NIL){ /*no value*/ lua_pop(L, 1); lua_pushnil(L); } lua_pushnil(L); lua_insert(L, -2); return 1; } return 0; }
void cell_touserdata(lua_State *L, int index, struct cell *c) { lua_rawgetp(L, index, c); if (lua_isuserdata(L, -1)) { return; } lua_pop(L,1); struct cell_ud * cud = lua_newuserdata(L, sizeof(*cud)); cud->c = c; cell_grab(c); if (luaL_newmetatable(L, "cell")) { lua_pushboolean(L,1); lua_rawsetp(L, -2, CELL_TAG); lua_pushcfunction(L, ltostring); lua_setfield(L, -2, "__tostring"); lua_pushcfunction(L, lrelease); lua_setfield(L, -2, "__gc"); } lua_setmetatable(L, -2); lua_pushvalue(L, -1); lua_rawsetp(L, index, c); }