int main() { lua_State *L = luaL_newstate(); int err; struct sockaddr_in send_to; luaL_openlibs(L); dmx = socket(AF_INET, SOCK_DGRAM, 0); send_to.sin_port = htons(21812); send_to.sin_family = AF_INET; if( inet_aton("127.0.0.1", &send_to.sin_addr) == 0 ){ printf("invalid address\n"); return EXIT_FAILURE; } if( connect(dmx, (struct sockaddr*)&send_to, sizeof(struct sockaddr_in)) < 0){ printf("couldn’t not connect socket\n"); return EXIT_FAILURE; } /*new_global_table(L, LIGHT); */ register_lt_functions(L); new_universe(L, "u"); new_group(L, "u", "group1"); err = luaL_loadfile(L, "lights.lua"); dbg_lua(L, err, "lights.lua"); err = lua_pcall(L, 0, LUA_MULTRET, 0); dbg_lua(L, err, "lights.lua"); new_light(L, 30, "u", "parled", "test1"); new_light(L, 5, "u", "parled", "test2"); new_light(L, 1, "u", "lspot", "spot1"); new_light(L, 2, "u", "lspot", "spot2"); new_light(L, 3, "u", "lspot", "spot3"); new_light(L, 4, "u", "lspot", "spot4"); link_into_group(L, "u", "group1", "test1"); link_into_group(L, "u", "group1", "test2"); err = luaL_loadfile(L, "test.lua"); dbg_lua(L, err, "test.lua"); err = lua_pcall(L, 0, LUA_MULTRET, 0); dbg_lua(L, err, "test.lua"); double p = 0; lua_getglobal(L, "main"); if( !lua_isfunction(L, -1) ){ printf("\"main\" function, is not defined\n"); return -1; } lua_pushnumber(L, p); err = lua_pcall(L, 1, 0, 0); dbg_lua(L, err, "main"); //update_lights(L, "u", cue); //printf("%g\r", p); //fflush(stdout); do{ lua_getglobal(L, "rt_time"); if( !lua_isfunction(L, -1) ){ printf("\"rt_time\" function, is not defined\n"); break; } err = lua_pcall(L, 0, 0, 0); dbg_lua(L, err, "rt_time"); }while(1); lua_close(L); close(dmx); return 0; }
LuaCFunc luaToFunction(lua_State* plua_state, int index, LuaCFunc default_function) { return lua_isfunction(plua_state, index) ? luaToFunction(plua_state, index) : default_function; }
bool CMLuaScript::Load() { status = Failed; if (luaL_loadfile(L, T2Utf(filePath))) { Log(lua_tostring(L, -1)); return false; } lua_createtable(L, 0, 2); lua_pushvalue(L, -1); lua_setfield(L, -2, "_G"); lua_pushlightuserdata(L, this); lua_setfield(L, -2, "Script"); lua_createtable(L, 0, 2); lua_getglobal(L, "_G"); lua_setfield(L, -2, "__index"); lua_setmetatable(L, -2); lua_setupvalue(L, -2, 1); if (luaM_pcall(L, 0, 1)) return false; status = Loaded; if (lua_isnoneornil(L, -1)) return true; luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, -1, moduleName); if (!lua_toboolean(L, -1)) { lua_pop(L, 1); lua_pushvalue(L, -2); lua_setfield(L, -2, moduleName); lua_pop(L, 1); } else lua_remove(L, -2); if (!lua_istable(L, -1)) return true; lua_getfield(L, -1, "Load"); if (lua_isfunction(L, -1)) luaM_pcall(L); else lua_pop(L, 1); lua_getfield(L, -1, "Unload"); if (lua_isfunction(L, -1)) { lua_pushvalue(L, -1); unloadRef = luaL_ref(L, LUA_REGISTRYINDEX); } lua_pop(L, 1); lua_pop(L, 1); return true; }
int LuaStack::executeFunction(int handler, int numArgs, int numResults, const std::function<void(lua_State*,int)>& func) { if (pushFunctionByHandler(handler)) /* L: ... arg1 arg2 ... func */ { if (numArgs > 0) { lua_insert(_state, -(numArgs + 1)); /* L: ... func arg1 arg2 ... */ } int functionIndex = -(numArgs + 1); if (!lua_isfunction(_state, functionIndex)) { CCLOG("value at stack [%d] is not function", functionIndex); lua_pop(_state, numArgs + 1); // remove function and arguments return 0; } int traceCallback = 0; lua_getglobal(_state, "__G__TRACKBACK__"); /* L: ... func arg1 arg2 ... G */ if (!lua_isfunction(_state, -1)) { lua_pop(_state, 1); /* L: ... func arg1 arg2 ... */ } else { lua_insert(_state, functionIndex - 1); /* L: ... G func arg1 arg2 ... */ traceCallback = functionIndex - 1; } int error = 0; ++_callFromLua; error = lua_pcall(_state, numArgs, numResults, traceCallback); /* L: ... [G] ret1 ret2 ... retResults*/ --_callFromLua; if (error) { if (traceCallback == 0) { CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1)); /* L: ... error */ lua_pop(_state, 1); // remove error message from stack } else /* L: ... G error */ { lua_pop(_state, 2); // remove __G__TRACKBACK__ and error message from stack } return 0; } // get return value,don't pass LUA_MULTRET to numResults, do { if (numResults <= 0 || nullptr == func) break; func(_state, numResults); } while (0); if (traceCallback) { lua_pop(_state, 1); // remove __G__TRACKBACK__ from stack /* L: ... */ } } return 1; }
/*** * @function rspamd_redis.make_request({params}) * Make request to redis server, params is a table of key=value arguments in any order * @param {task} task worker task object * @param {ip} host server address * @param {function} callback callback to be called in form `function (task, err, data)` * @param {string} cmd command to be sent to redis * @param {table} args numeric array of strings used as redis arguments * @param {number} timeout timeout in seconds for request (1.0 by default) * @return {boolean} `true` if a request has been scheduled */ static int lua_redis_make_request (lua_State *L) { struct lua_redis_userdata *ud; struct rspamd_lua_ip *addr = NULL; struct rspamd_task *task = NULL; const gchar *cmd = NULL; gint top, cbref = -1; struct timeval tv; gboolean ret = FALSE; gdouble timeout = REDIS_DEFAULT_TIMEOUT; if (lua_istable (L, 1)) { /* Table version */ lua_pushstring (L, "task"); lua_gettable (L, -2); if (lua_type (L, -1) == LUA_TUSERDATA) { task = lua_check_task (L, -1); } lua_pop (L, 1); lua_pushstring (L, "callback"); lua_gettable (L, -2); if (lua_type (L, -1) == LUA_TFUNCTION) { /* This also pops function from the stack */ cbref = luaL_ref (L, LUA_REGISTRYINDEX); } else { msg_err ("bad callback argument for lua redis"); lua_pop (L, 1); } lua_pushstring (L, "cmd"); lua_gettable (L, -2); cmd = lua_tostring (L, -1); lua_pop (L, 1); lua_pushstring (L, "host"); lua_gettable (L, -2); if (lua_type (L, -1) == LUA_TUSERDATA) { addr = lua_check_ip (L, -1); } lua_pop (L, 1); lua_pushstring (L, "timeout"); lua_gettable (L, -2); timeout = lua_tonumber (L, -1); lua_pop (L, 1); if (task != NULL && addr != NULL && cbref != -1 && cmd != NULL) { ud = rspamd_mempool_alloc (task->task_pool, sizeof (struct lua_redis_userdata)); ud->task = task; ud->L = L; ud->cbref = cbref; lua_pushstring (L, "args"); lua_redis_parse_args (L, -1, cmd, ud); ret = TRUE; } else { if (cbref != -1) { luaL_unref (L, LUA_REGISTRYINDEX, cbref); } msg_err ("incorrect function invocation"); } } else if ((task = lua_check_task (L, 1)) != NULL) { addr = lua_check_ip (L, 2); top = lua_gettop (L); /* Now get callback */ if (lua_isfunction (L, 3) && addr != NULL && addr->addr && top >= 4) { /* Create userdata */ ud = rspamd_mempool_alloc (task->task_pool, sizeof (struct lua_redis_userdata)); ud->task = task; ud->L = L; /* Pop other arguments */ lua_pushvalue (L, 3); /* Get a reference */ ud->cbref = luaL_ref (L, LUA_REGISTRYINDEX); cmd = luaL_checkstring (L, 4); if (top > 4) { lua_redis_parse_args (L, 5, cmd, ud); } else { lua_redis_parse_args (L, 0, cmd, ud); } ret = TRUE; } else { msg_err ("incorrect function invocation"); } } if (ret) { ud->terminated = 0; ud->ctx = redisAsyncConnect (rspamd_inet_address_to_string (addr->addr), rspamd_inet_address_get_port (addr->addr)); redisAsyncSetConnectCallback (ud->ctx, lua_redis_connect_cb); if (ud->ctx == NULL || ud->ctx->err) { ud->terminated = 1; redisAsyncFree (ud->ctx); lua_redis_free_args (ud); luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref); lua_pushboolean (L, FALSE); return 1; } redisLibeventAttach (ud->ctx, ud->task->ev_base); ret = redisAsyncCommandArgv (ud->ctx, lua_redis_callback, ud, ud->nargs, (const gchar **)ud->args, NULL); if (ret == REDIS_OK) { rspamd_session_add_event (ud->task->s, lua_redis_fin, ud, g_quark_from_static_string ("lua redis")); double_to_tv (timeout, &tv); event_set (&ud->timeout, -1, EV_TIMEOUT, lua_redis_timeout, ud); event_base_set (ud->task->ev_base, &ud->timeout); event_add (&ud->timeout, &tv); } else { msg_info ("call to redis failed: %s", ud->ctx->errstr); ud->terminated = 1; lua_redis_free_args (ud); redisAsyncFree (ud->ctx); luaL_unref (ud->L, LUA_REGISTRYINDEX, ud->cbref); } } lua_pushboolean (L, ret); return 1; }
int luaQ_complete(struct lua_State *L) { int k = 0; int loop = 0; const char *stem = luaL_checkstring(L, 1); lua_pushvalue(L, LUA_GLOBALSINDEX); for(;;) { const char *s = stem; while (*s && *s != '.' && *s != ':') s++; if (*s == 0) break; // stack: table str lua_pushlstring(L, stem, s-stem); lua_gettable(L, -2); // stack: ntable table str lua_replace(L, -2); // stack: ntable str stem = s + 1; } lua_createtable(L, 0, 0); lua_insert(L, -2); // stack: maybetable anstable str if (lua_isuserdata(L, -1) && lua_getmetatable(L, -1)) { lua_replace(L, -2); lua_pushliteral(L, "__index"); lua_rawget(L, -2); if (lua_isfunction(L, -1)) { lua_pop(L, 1); lua_pushliteral(L, "__metatable"); lua_rawget(L, -2); } lua_replace(L, -2); } if (! lua_istable(L, -1)) { lua_pop(L, 1); return 1; } // stack: table anstable str size_t stemlen = strlen(stem); for(;;) { lua_pushnil(L); while (lua_next(L, -2)) { // stack: value key table anstable str bool ok = false; size_t keylen; const char *key = lua_tolstring(L, -2, &keylen); if (key && keylen > 0 && keylen >= stemlen) if (!strncmp(key, stem, stemlen)) ok = true; if (ok && stemlen==0 && !isalpha(key[0])) ok = false; if (ok) for (int i=0; ok && i<(int)keylen; i++) if (!isalpha(key[i]) && !isdigit(key[i]) && key[i]!='_') ok = false; if (ok) { const char *suffix = ""; switch (lua_type(L, -1)) { case LUA_TFUNCTION: suffix = "("; break; case LUA_TTABLE: suffix = "."; luaQ_getfield(L, -1, "_C"); if (lua_istable(L, -1)) suffix = ":"; lua_pop(L, 1); break; case LUA_TUSERDATA: { QVariant v = luaQ_toqvariant(L, -1); const char *s = QMetaType::typeName(v.userType()); if (s && !strcmp(s,"QtLuaMethodInfo")) suffix = "("; else if (s && !strcmp(s, "QtLuaPropertyInfo")) suffix = ""; else if (lua_getmetatable(L, -1)) { lua_pop(L, 1); suffix = ":"; } else suffix = ""; } break; default: break; } // stack: value key table anstable str lua_pushfstring(L, "%s%s", key+stemlen, suffix); lua_rawseti(L, -5, ++k); } lua_pop(L, 1); } // stack: table anstable str if (! lua_getmetatable(L, -1)) break; lua_replace(L, -2); lua_pushliteral(L, "__index"); lua_rawget(L, -2); if (lua_isfunction(L, -1)) { lua_pop(L, 1); lua_pushliteral(L, "__metatable"); lua_rawget(L, -2); } lua_replace(L, -2); if (! lua_istable(L, -1)) break; if (++loop > 100) luaL_error(L, "complete: infinite loop in metatables"); } // stack: something anstable str lua_pop(L, 1); lua_replace(L, -2); return 1; }
/***************************************************************************** * FillDescriptor: call the descriptor function and fill the structure ****************************************************************************/ static int FillDescriptor( services_discovery_t *p_sd, services_discovery_descriptor_t *p_desc ) { services_discovery_sys_t *p_sys = p_sd->p_sys; int i_ret = VLC_EGENERIC; /* Create a new lua thread */ lua_State *L = luaL_newstate(); if( luaL_dofile( L, p_sys->psz_filename ) ) { msg_Err( p_sd, "Error loading script %s: %s", p_sys->psz_filename, lua_tostring( L, -1 ) ); goto end; } /* Call the "descriptor" function */ lua_getglobal( L, "descriptor" ); if( !lua_isfunction( L, -1 ) || lua_pcall( L, 0, 1, 0 ) ) { msg_Warn( p_sd, "Error getting the descriptor in '%s': %s", p_sys->psz_filename, lua_tostring( L, -1 ) ); goto end; } /* Get the different fields of the returned table */ lua_getfield( L, -1, "short_description" ); p_desc->psz_short_desc = luaL_strdupornull( L, -1 ); lua_pop( L, 1 ); lua_getfield( L, -1, "icon" ); p_desc->psz_icon_url = luaL_strdupornull( L, -1 ); lua_pop( L, 1 ); lua_getfield( L, -1, "url" ); p_desc->psz_url = luaL_strdupornull( L, -1 ); lua_pop( L, 1 ); lua_getfield( L, -1, "capabilities" ); p_desc->i_capabilities = 0; if( lua_istable( L, -1 ) ) { /* List all table entries */ lua_pushnil( L ); while( lua_next( L, -2 ) != 0 ) { /* Key is at index -2 and value at index -1 */ const char *psz_cap = luaL_checkstring( L, -1 ); int i_cap = 0; const char *psz_iter; for( psz_iter = *ppsz_capabilities; psz_iter; psz_iter = ppsz_capabilities[ ++i_cap ] ) { if( !strcmp( psz_iter, psz_cap ) ) { p_desc->i_capabilities |= 1 << i_cap; break; } } lua_pop( L, 1 ); if( !psz_iter ) msg_Warn( p_sd, "Services discovery capability '%s' unknown in " "script '%s'", psz_cap, p_sys->psz_filename ); } } lua_pop( L, 1 ); i_ret = VLC_SUCCESS; end: lua_close( L ); return i_ret; }
int luabridge::indexer (lua_State *L) { lua_getmetatable(L, 1); do { // Look for the key in the metatable lua_pushvalue(L, 2); lua_rawget(L, -2); // Did we get a non-nil result? If so, return it if (!lua_isnil(L, -1) ) return 1; ///pop the nil lua_pop(L, 1); //search the metatable of the object's metatable. if( lua_getmetatable(L, -1) && !lua_isnil(L, -1) ) { //to prevent calling this indexer method again, make sure the found metatable is not equal to the table's metatable. if( !lua_rawequal(L, -1, -2) ) { //store our current argument cnt so we can determine if any arguments were pushed ptrdiff_t base = lua_gettop(L), top; //push the method name being called lua_pushvalue(L,2); //try to retrieve the key and allow any events to be called. lua_gettable(L,-2); //if there were any arguments, return those. top = lua_gettop(L); //check for multiple arguments. if( top > (base+1) ) return (top - base); //check if the returned object is nil else if(top == (base+1) && !lua_isnil(L, -1) ) return 1; else if(top == (base+1) && lua_isnil(L, -1 )) lua_pop(L,1); //otherwise, proceed w/ other checks. } //pop the metatable's metatable. lua_pop(L, 1); } // Look for the key in the __propget metafield rawgetfield(L, -1, "__propget"); if (!lua_isnil(L, -1)) { lua_pushvalue(L, 2); lua_rawget(L, -2); // If we got a non-nil result, call it and return its value if (!lua_isnil(L, -1)) { assert(lua_isfunction(L, -1)); lua_pushvalue(L, 1); lua_call(L, 1, 1); return 1; } lua_pop(L, 1); } lua_pop(L, 1); // Look for the key in the __const metafield rawgetfield(L, -1, "__const"); if (!lua_isnil(L, -1)) { lua_pushvalue(L, 2); lua_rawget(L, -2); if (!lua_isnil(L, -1)) return 1; lua_pop(L, 1); } lua_pop(L, 1); // Look for a __parent metafield; if it doesn't exist, return nil; // otherwise, repeat the lookup on it. rawgetfield(L, -1, "__parent"); if (lua_isnil(L, -1)) return 1; lua_remove(L, -2); } while (true); // Control never gets here return 0; }
void LuaState::call( const std::string& callbackName, int registryIndex, bool exception ) { TRACE_ENTERLEAVE(); TRACE( "callback name: %s, callback index %d", callbackName.c_str(), registryIndex ); // // load debug.traceback // lua_getglobal( m_lua, "debug" ); lua_getfield( m_lua, -1, "traceback" ); int debugIndex = -2; // // load callback function to the top of the stack // if ( registryIndex < 0 ) { // // push function identified by global name to the stack // lua_getglobal( m_lua, "__leda" ); lua_getfield( m_lua, -1, callbackName.c_str() ); debugIndex = -3; } else { // // push function identified by registry index to the stack // lua_rawgeti( m_lua, LUA_REGISTRYINDEX, registryIndex ); } if ( !lua_isfunction( m_lua, -1 ) ) { TRACE( "no lua function found on top of stack", "" ); lua_pop( m_lua, -debugIndex + 1 ); return; } // // call lua callback function // int result = lua_pcall( m_lua, 0, 0, debugIndex ); TRACE( "lua call result: %d", result ); if ( result > 0 ) { // // error executing lua // const char* error = lua_tostring( m_lua, -1 ); TRACE_ERROR( "%s", error ); lua_pop( m_lua, -debugIndex + 1 ); std::string errorString; if ( error ) { errorString = error; } if ( exception ) { throw std::runtime_error( errorString ); } return; } // // pop all from stack // lua_pop( m_lua, -debugIndex ); }
int main(int argc, char *argv[]) { struct hostent *server_host; char *server_host_str = "localhost"; char *certificate_file = NULL; char *key_file = NULL; char *password_file = NULL; char *token_file = NULL; char *username = "******"; int port = 64738; int ret; int development_mode = 0; int socket_fd; struct sockaddr_in server_addr; SSLRead socket_watcher; ev_io user_thread_watcher; ev_timer ping_watcher; ev_signal signal_watcher; ev_loop_main = EV_DEFAULT; /* * Lua initialization */ lua = luaL_newstate(); if (lua == NULL) { fprintf(stderr, "%s: could not initialize Lua\n", PIEPAN_NAME); return 1; } luaL_openlibs(lua); if (luaL_loadbuffer(lua, (const char *)src_piepan_impl_luac, src_piepan_impl_luac_len, "piepan_impl") != LUA_OK) { fprintf(stderr, "%s: could not load piepan implementation\n", PIEPAN_NAME); return 1; } lua_call(lua, 0, 0); lua_getglobal(lua, "piepan"); lua_getfield(lua, -1, "internal"); lua_getfield(lua, -1, "api"); lua_pushcfunction(lua, api_init); lua_setfield(lua, -2, "apiInit"); lua_settop(lua, 0); /* * Argument parsing */ { int opt; int i; int show_help = 0; int show_version = 0; lua_getglobal(lua, "piepan"); lua_getfield(lua, -1, "internal"); lua_getfield(lua, -1, "events"); lua_getfield(lua, -1, "onArgument"); opterr = 0; while ((opt = getopt(argc, argv, "u:c:k:s:t:p:-:dhv")) != -1) { switch (opt) { case 'u': username = optarg; break; case 'c': certificate_file = optarg; if (key_file == NULL) { key_file = certificate_file; } break; case 'k': key_file = optarg; break; case 's': { char *port_str; server_host_str = optarg; port_str = strrchr(server_host_str, ':'); if (port_str != NULL) { *port_str = '\0'; port = atoi(++port_str); } break; } case 't': token_file = optarg; break; case 'p': password_file = optarg; break; case '-': { char *key = optarg; char *value = strchr(key, '='); if (key == value) { break; } if (value != NULL) { *value++ = 0; } lua_pushvalue(lua, -1); lua_pushstring(lua, key); lua_pushstring(lua, value); lua_call(lua, 2, 0); break; } case 'd': development_mode = 1; break; case 'h': usage(stdout); return 0; case 'v': printf("%s %s (compiled on " __DATE__ " " __TIME__ ")\n", PIEPAN_NAME, PIEPAN_VERSION); return 0; default: fprintf(stderr, "%s: unknown or incomplete option '%c'\n", PIEPAN_NAME, optopt); return 1; } } lua_settop(lua, 0); } /* * Load user scripts */ { int i; lua_getglobal(lua, "piepan"); lua_getfield(lua, -1, "internal"); lua_getfield(lua, -1, "events"); lua_getfield(lua, -1, "onLoadScript"); for (i = optind; i < argc; i++) { lua_pushvalue(lua, -1); lua_pushstring(lua, argv[i]); if (development_mode) { lua_newuserdata(lua, sizeof(ScriptStat)); } else { lua_pushnil(lua); } lua_call(lua, 2, 3); if (lua_toboolean(lua, -3)) { if (development_mode) { ScriptStat *item = lua_touserdata(lua, -1); item->lua = lua; item->id = lua_tointeger(lua, -2); item->filename = argv[i]; ev_stat_init(&item->ev, script_stat_event, item->filename, 0); ev_stat_start(ev_loop_main, &item->ev); } } else { fprintf(stderr, "%s: %s\n", PIEPAN_NAME, lua_tostring(lua, -2)); } lua_pop(lua, 3); } lua_settop(lua, 0); } /* * Initialize Opus */ { OpusEncoder *encoder; int error; lua_getglobal(lua, "piepan"); lua_getfield(lua, -1, "internal"); lua_getfield(lua, -1, "opus"); encoder = lua_newuserdata(lua, opus_encoder_get_size(1)); lua_setfield(lua, -2, "encoder"); error = opus_encoder_init(encoder, 48000, 1, OPUS_APPLICATION_AUDIO); if (error != OPUS_OK) { fprintf(stderr, "%s: could not initialize the Opus encoder: %s\n", PIEPAN_NAME, opus_strerror(error)); return 1; } opus_encoder_ctl(encoder, OPUS_SET_VBR(0)); /* TODO: set this to the server's max bitrate */ opus_encoder_ctl(encoder, OPUS_SET_BITRATE(40000)); lua_settop(lua, 0); } /* * SSL initialization */ SSL_library_init(); ssl_context = SSL_CTX_new(SSLv23_client_method()); if (ssl_context == NULL) { fprintf(stderr, "%s: could not create SSL context\n", PIEPAN_NAME); return 1; } if (certificate_file != NULL) { if (!SSL_CTX_use_certificate_chain_file(ssl_context, certificate_file) || !SSL_CTX_use_PrivateKey_file(ssl_context, key_file, SSL_FILETYPE_PEM) || !SSL_CTX_check_private_key(ssl_context)) { fprintf(stderr, "%s: could not load certificate and/or key file\n", PIEPAN_NAME); return 1; } } /* * Socket initialization and connection */ socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 0) { fprintf(stderr, "%s: could not create socket\n", PIEPAN_NAME); return 1; } memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(port); server_host = gethostbyname(server_host_str); if (server_host == NULL || server_host->h_addr_list[0] == NULL || server_host->h_addrtype != AF_INET) { fprintf(stderr, "%s: could not parse server address\n", PIEPAN_NAME); return 1; } memmove(&server_addr.sin_addr, server_host->h_addr_list[0], server_host->h_length); ret = connect(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)); if (ret != 0) { fprintf(stderr, "%s: could not connect to server\n", PIEPAN_NAME); return 1; } ssl = SSL_new(ssl_context); if (ssl == NULL) { fprintf(stderr, "%s: could not create SSL object\n", PIEPAN_NAME); return 1; } if (SSL_set_fd(ssl, socket_fd) == 0) { fprintf(stderr, "%s: could not set SSL file descriptor\n", PIEPAN_NAME); return 1; } if (SSL_connect(ssl) != 1) { fprintf(stderr, "%s: could not create secure connection\n", PIEPAN_NAME); return 1; } /* * User thread pipe */ if (pipe(user_thread_pipe) != 0) { fprintf(stderr, "%s: could not create user thread pipe\n", PIEPAN_NAME); return 1; } /* * Trigger initial event */ lua_getglobal(lua, "piepan"); lua_getfield(lua, -1, "internal"); lua_getfield(lua, -1, "initialize"); lua_newtable(lua); lua_pushstring(lua, username); lua_setfield(lua, -2, "username"); if (password_file != NULL) { lua_pushstring(lua, password_file); lua_setfield(lua, -2, "passwordFile"); } if (token_file != NULL) { lua_pushstring(lua, token_file); lua_setfield(lua, -2, "tokenFile"); } lua_pushlightuserdata(lua, lua); lua_setfield(lua, -2, "state"); lua_call(lua, 1, 0); lua_settop(lua, 0); /* * Event loop */ ev_signal_init(&signal_watcher, signal_event, SIGINT); ev_signal_start(ev_loop_main, &signal_watcher); ev_io_init(&socket_watcher.ev, socket_read_event, socket_fd, EV_READ); socket_watcher.lua = lua; socket_watcher.ssl = ssl; ev_io_start(ev_loop_main, &socket_watcher.ev); ev_io_init(&user_thread_watcher, user_thread_event, user_thread_pipe[0], EV_READ); ev_io_start(ev_loop_main, &user_thread_watcher); ev_timer_init(&ping_watcher, ping_event, PING_TIMEOUT, PING_TIMEOUT); ev_timer_start(ev_loop_main, &ping_watcher); ev_run(ev_loop_main, 0); /* * Cleanup */ lua_getglobal(lua, "piepan"); lua_getfield(lua, -1, "internal"); lua_getfield(lua, -1, "events"); lua_getfield(lua, -1, "onDisconnect"); if (lua_isfunction(lua, -1)) { lua_newtable(lua); lua_call(lua, 1, 0); } SSL_shutdown(ssl); /* TODO: sigpipe is triggered here if connection breaks */ close(socket_fd); lua_close(lua); return 0; }
static int lluv_tcp_bind(lua_State *L){ static const lluv_uv_const_t FLAGS[] = { { UV_TCP_IPV6ONLY , "ipv6only" }, { 0, NULL } }; lluv_handle_t *handle = lluv_check_tcp(L, 1, LLUV_FLAG_OPEN); struct sockaddr_storage sa; int err = lluv_check_addr(L, 2, &sa); unsigned int flags = 0; int top = lua_gettop(L); if(top > 5)lua_settop(L, top = 5); if((top > 4) || (!lua_isfunction(L, 4))){ flags = lluv_opt_flags_ui(L, 4, flags, FLAGS); } if(err < 0){ lua_checkstack(L, 3); lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3); if(!lua_isfunction(L, top)){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1)); lua_remove(L, -2); lua_pushvalue(L, 1); lua_insert(L, -2); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2); lua_settop(L, 1); return 1; } err = uv_tcp_bind(LLUV_H(handle, uv_tcp_t), (struct sockaddr *)&sa, flags); if(err < 0){ lua_checkstack(L, 3); lua_pushvalue(L, 2); lua_pushliteral(L, ":"); lua_pushvalue(L, 3); lua_concat(L, 3); if(!lua_isfunction(L, top)){ return lluv_fail(L, handle->flags, LLUV_ERR_UV, err, lua_tostring(L, -1)); } lluv_error_create(L, LLUV_ERR_UV, err, lua_tostring(L, -1)); lua_remove(L, -2); lua_pushvalue(L, 1); lua_insert(L, -2); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), 2); lua_settop(L, 1); return 1; } if(lua_isfunction(L, top)){ lua_pushvalue(L, 1); lua_pushnil(L); lluv_loop_defer_call(L, lluv_loop_by_handle(&handle->handle), lluv_push_addr(L, &sa) + 2 ); } lua_settop(L, 1); return 1; }
static int js_generator_value(lua_State *L) { int max; int is_array; int no_vals; int type = lua_type(L, 2); switch ( type ) { case LUA_TNIL: return js_generator_null(L); case LUA_TNUMBER: return js_generator_number(L); case LUA_TBOOLEAN: return js_generator_boolean(L); case LUA_TSTRING: return js_generator_string(L); case LUA_TUSERDATA: if ( lua_topointer(L, 2) == js_null ) { return js_generator_null(L); } case LUA_TLIGHTUSERDATA: case LUA_TTABLE: case LUA_TFUNCTION: case LUA_TTHREAD: if ( luaL_getmetafield(L, 2, "__gen_json") ) { if ( lua_isfunction(L, -1) ) { lua_settop(L, 3); /* gen, obj, func */ lua_insert(L, 1); /* func, gen, obj */ lua_insert(L, 2); /* func, obj, gen */ lua_call(L, 2, 0); return 0; } lua_pop(L, 1); } /* Simply ignore it, perhaps we should warn? */ if ( type != LUA_TTABLE ) { js_generator_open_object(L); js_generator_close(L); return 0; } max = 0; is_array = 1; no_vals = 1; /* First iterate over the table to see if it is an array: */ lua_pushnil(L); while ( lua_next(L, 2) != 0 ) { no_vals = 0; if ( lua_type(L, -2) == LUA_TNUMBER ) { double num = lua_tonumber(L, -2); if ( num == floor(num) ) { if ( num > max ) max = num; } else { lua_pop(L, 2); is_array = 0; break; } } else if (lua_type(L, -2) == LUA_TSTRING && strncmp(lua_tostring(L, -2), "length", 6) == 0) { // ignore "length" } else { lua_pop(L, 2); is_array = 0; break; } lua_pop(L, 1); } if ( is_array && !no_vals ) { int i; js_generator_open_array(L); for ( i=0; i <= max; i++ ) { lua_pushinteger(L, i); lua_gettable(L, 2); /* RECURSIVE CALL: gen, obj, ?, val, func, gen, val */ lua_pushcfunction(L, js_generator_value); lua_pushvalue(L, 1); lua_pushvalue(L, -3); lua_call(L, 2, 0); lua_pop(L, 1); } } else { js_generator_open_object(L); lua_pushnil(L); while ( lua_next(L, 2) != 0 ) { /* gen, obj, ?, key, val, func, gen, key */ lua_pushcfunction(L, js_generator_string); lua_pushvalue(L, 1); if ( lua_isstring(L, -4) ) { lua_pushvalue(L, -4); } else { /* Must coerce into a string: */ lua_getglobal(L, "tostring"); lua_pushvalue(L, -5); lua_call(L, 1, 1); } /* support replacer */ lua_getfenv(L, 1); lua_getfield(L, -1, "replacer"); lua_remove(L, -2); if (!lua_isnil(L, -1)) { lua_pushvalue(L, 2); lua_pushvalue(L, -7); lua_pushvalue(L, -7); lua_call(L, 3, 1); if (lua_isnil(L, -1)) { lua_remove(L, -1); continue; } else { lua_replace(L, -5); } } else { lua_remove(L, -1); } /* push key */ lua_call(L, 2, 0); /* RECURSIVE CALL: gen, obj, ?, key, val, func, gen, val */ lua_pushcfunction(L, js_generator_value); lua_pushvalue(L, 1); lua_pushvalue(L, -3); lua_call(L, 2, 0); lua_pop(L, 1); } } js_generator_close(L); return 0; case LUA_TNONE: lua_pushfstring(L, "MissingArgument: second parameter to js_generator_value() must be defined at %s line %d", type, __FILE__, __LINE__); default: lua_pushfstring(L, "Unreachable: js_generator_value passed lua type (%d) not recognized at %s line %d", type, __FILE__, __LINE__); } /* Shouldn't get here: */ lua_error(L); return 0; }
JNIEXPORT jboolean JNICALL Java_m_lua_Lua_isFunction (JNIEnv* env, jobject thiz, jlong nativeObj, jint idx) { return (jboolean) lua_isfunction((lua_State*) nativeObj, idx); }
/** * walk through the content array * * content = { "<pre>", { file = "/content" } , "</pre>" } * * header["Content-Type"] = "text/html" * * return 200 */ static int magnet_attach_content(server *srv, connection *con, plugin_data *p, lua_State *L) { UNUSED(p); /** * get the environment of the function */ force_assert(lua_isfunction(L, -1)); lua_getfenv(L, -1); /* -1 is the function */ lua_getfield(L, -1, "lighty"); /* lighty.* from the env */ force_assert(lua_istable(L, -1)); lua_getfield(L, -1, "content"); /* lighty.content */ if (lua_istable(L, -1)) { int i; /* header is found, and is a table */ for (i = 1; ; i++) { lua_rawgeti(L, -1, i); /* -1 is the value and should be the value ... aka a table */ if (lua_isstring(L, -1)) { size_t s_len = 0; const char *s = lua_tolstring(L, -1, &s_len); chunkqueue_append_mem(con->write_queue, s, s_len); } else if (lua_istable(L, -1)) { lua_getfield(L, -1, "filename"); lua_getfield(L, -2, "length"); lua_getfield(L, -3, "offset"); if (lua_isstring(L, -3)) { /* filename has to be a string */ buffer *fn; stat_cache_entry *sce; const char *fn_str; handler_t res; fn_str = lua_tostring(L, -3); fn = buffer_init_string(fn_str); res = stat_cache_get_entry(srv, con, fn, &sce); if (HANDLER_GO_ON == res) { off_t off = 0; off_t len = 0; if (lua_isnumber(L, -1)) { off = lua_tonumber(L, -1); } if (lua_isnumber(L, -2)) { len = lua_tonumber(L, -2); } else { len = sce->st.st_size; } if (off < 0) { buffer_free(fn); return luaL_error(L, "offset for '%s' is negative", fn_str); } if (len < off) { buffer_free(fn); return luaL_error(L, "offset > length for '%s'", fn_str); } chunkqueue_append_file(con->write_queue, fn, off, len - off); } buffer_free(fn); } else { lua_pop(L, 3 + 2); /* correct the stack */ return luaL_error(L, "content[%d] is a table and requires the field \"filename\"", i); } lua_pop(L, 3); } else if (lua_isnil(L, -1)) { /* oops, end of list */ lua_pop(L, 1); break; } else { lua_pop(L, 4); return luaL_error(L, "content[%d] is neither a string nor a table: ", i); } lua_pop(L, 1); /* pop the content[...] table */ } } else { return luaL_error(L, "lighty.content has to be a table"); } lua_pop(L, 1); /* pop the header-table */ lua_pop(L, 1); /* pop the lighty-table */ lua_pop(L, 1); /* php the function env */ return 0; }
ContentFeatures read_content_features(lua_State *L, int index) { if(index < 0) index = lua_gettop(L) + 1 + index; ContentFeatures f; /* Cache existence of some callbacks */ lua_getfield(L, index, "on_construct"); if(!lua_isnil(L, -1)) f.has_on_construct = true; lua_pop(L, 1); lua_getfield(L, index, "on_destruct"); if(!lua_isnil(L, -1)) f.has_on_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "after_destruct"); if(!lua_isnil(L, -1)) f.has_after_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "on_rightclick"); f.rightclickable = lua_isfunction(L, -1); lua_pop(L, 1); /* Name */ getstringfield(L, index, "name", f.name); /* Groups */ lua_getfield(L, index, "groups"); read_groups(L, -1, f.groups); lua_pop(L, 1); /* Visual definition */ f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", ScriptApiNode::es_DrawType,NDT_NORMAL); getfloatfield(L, index, "visual_scale", f.visual_scale); /* Meshnode model filename */ getstringfield(L, index, "mesh", f.mesh); // tiles = {} lua_getfield(L, index, "tiles"); // If nil, try the deprecated name "tile_images" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "tile_images", "Deprecated; new name is \"tiles\"."); lua_getfield(L, index, "tile_images"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef[i] = read_tiledef(L, -1); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==6){ lua_pop(L, 1); break; } } // Copy last value to all remaining textures if(i >= 1){ TileDef lasttile = f.tiledef[i-1]; while(i < 6){ f.tiledef[i] = lasttile; i++; } } } lua_pop(L, 1); // special_tiles = {} lua_getfield(L, index, "special_tiles"); // If nil, try the deprecated name "special_materials" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "special_materials", "Deprecated; new name is \"special_tiles\"."); lua_getfield(L, index, "special_materials"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef_special[i] = read_tiledef(L, -1); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==CF_SPECIAL_COUNT){ lua_pop(L, 1); break; } } } lua_pop(L, 1); f.alpha = getintfield_default(L, index, "alpha", 255); bool usealpha = getboolfield_default(L, index, "use_texture_alpha", false); if (usealpha) f.alpha = 0; /* Other stuff */ lua_getfield(L, index, "post_effect_color"); read_color(L, -1, &f.post_effect_color); lua_pop(L, 1); f.param_type = (ContentParamType)getenumfield(L, index, "paramtype", ScriptApiNode::es_ContentParamType, CPT_NONE); f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2", ScriptApiNode::es_ContentParamType2, CPT2_NONE); // Warn about some deprecated fields warn_if_field_exists(L, index, "wall_mounted", "deprecated: use paramtype2 = 'wallmounted'"); warn_if_field_exists(L, index, "light_propagates", "deprecated: determined from paramtype"); warn_if_field_exists(L, index, "dug_item", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item_rarity", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "metadata_name", "deprecated: use on_add and metadata callbacks"); // True for all ground-like things like stone and mud, false for eg. trees getboolfield(L, index, "is_ground_content", f.is_ground_content); f.light_propagates = (f.param_type == CPT_LIGHT); getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates); // This is used for collision detection. // Also for general solidness queries. getboolfield(L, index, "walkable", f.walkable); // Player can point to these getboolfield(L, index, "pointable", f.pointable); // Player can dig these getboolfield(L, index, "diggable", f.diggable); // Player can climb these getboolfield(L, index, "climbable", f.climbable); // Player can build on these getboolfield(L, index, "buildable_to", f.buildable_to); // Whether the node is non-liquid, source liquid or flowing liquid f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype", ScriptApiNode::es_LiquidType, LIQUID_NONE); // If the content is liquid, this is the flowing version of the liquid. getstringfield(L, index, "liquid_alternative_flowing", f.liquid_alternative_flowing); // If the content is liquid, this is the source version of the liquid. getstringfield(L, index, "liquid_alternative_source", f.liquid_alternative_source); // Viscosity for fluid flow, ranging from 1 to 7, with // 1 giving almost instantaneous propagation and 7 being // the slowest possible f.liquid_viscosity = getintfield_default(L, index, "liquid_viscosity", f.liquid_viscosity); f.liquid_range = getintfield_default(L, index, "liquid_range", f.liquid_range); f.leveled = getintfield_default(L, index, "leveled", f.leveled); getboolfield(L, index, "liquid_renewable", f.liquid_renewable); f.drowning = getintfield_default(L, index, "drowning", f.drowning); // Amount of light the node emits f.light_source = getintfield_default(L, index, "light_source", f.light_source); f.damage_per_second = getintfield_default(L, index, "damage_per_second", f.damage_per_second); lua_getfield(L, index, "node_box"); if(lua_istable(L, -1)) f.node_box = read_nodebox(L, -1); lua_pop(L, 1); lua_getfield(L, index, "selection_box"); if(lua_istable(L, -1)) f.selection_box = read_nodebox(L, -1); lua_pop(L, 1); lua_getfield(L, index, "collision_box"); if(lua_istable(L, -1)) f.collision_box = read_nodebox(L, -1); lua_pop(L, 1); f.waving = getintfield_default(L, index, "waving", f.waving); // Set to true if paramtype used to be 'facedir_simple' getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple); // Set to true if wall_mounted used to be set to true getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted); // Sound table lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "footstep"); read_soundspec(L, -1, f.sound_footstep); lua_pop(L, 1); lua_getfield(L, -1, "dig"); read_soundspec(L, -1, f.sound_dig); lua_pop(L, 1); lua_getfield(L, -1, "dug"); read_soundspec(L, -1, f.sound_dug); lua_pop(L, 1); } lua_pop(L, 1); return f; }
/* Lua only functions */ int luaT_lua_newmetatable(lua_State *L) { const char* tname = luaL_checkstring(L, 1); const void *id; lua_settop(L, 5); luaL_argcheck(L, lua_isnoneornil(L, 2) || lua_isstring(L, 2), 2, "parent class name or nil expected"); luaL_argcheck(L, lua_isnoneornil(L, 3) || lua_isfunction(L, 3), 3, "constructor function or nil expected"); luaL_argcheck(L, lua_isnoneornil(L, 4) || lua_isfunction(L, 4), 4, "destructor function or nil expected"); luaL_argcheck(L, lua_isnoneornil(L, 5) || lua_isfunction(L, 5), 5, "factory function or nil expected"); if(luaT_classmodulename(tname)) lua_getfield(L, LUA_GLOBALSINDEX, luaT_classmodulename(tname)); else lua_pushvalue(L, LUA_GLOBALSINDEX); if(!lua_istable(L, 6)) luaL_error(L, "while creating metatable %s: bad ardument #1 (%s is an invalid module name)", tname, luaT_classmodulename(tname)); /* we first create the new metaclass if we have to */ if(!luaT_typename2id(L, tname)) { /* create the metaclass */ lua_newtable(L); id = lua_topointer(L, -1); /* id = pointer on metaclass */ /* __index points on itself */ lua_pushvalue(L, -1); lua_setfield(L, -2, "__index"); /* __typename contains the typename */ lua_pushstring(L, tname); lua_setfield(L, -2, "__typename"); /* by default, __version equals 1 */ lua_pushnumber(L, 1); lua_setfield(L, -2, "__version"); /* register in "*torch.id2tname*" registry table (id -> typename) */ lua_getfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*"); if(lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*"); lua_getfield(L, LUA_REGISTRYINDEX, "*torch.id2tname*"); } lua_pushlightuserdata(L, (void*)id); lua_pushstring(L, tname); lua_settable(L, -3); lua_pop(L, 1); /* register in "*torch.tname2id*" registry table (typename -> id) */ lua_getfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*"); if(lua_isnil(L, -1)) { lua_pop(L, 1); lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*"); lua_getfield(L, LUA_REGISTRYINDEX, "*torch.tname2id*"); } lua_pushstring(L, tname); lua_pushlightuserdata(L, (void*)id); lua_settable(L, -3); lua_pop(L, 1); } /* we retrieve the existing metaclass */ else { id = luaT_typename2id(L, tname); luaT_pushmetaclass(L, id); } /* we assign the parent class if necessary */ if(!lua_isnoneornil(L, 2)) { if(lua_getmetatable(L, -1)) luaL_error(L, "class %s has been already assigned a parent class\n", tname); else { const char* parenttname = luaL_checkstring(L, 2); luaT_pushmetaclass(L, luaT_typename2id(L, parenttname)); if(lua_isnil(L, -1)) luaL_error(L, "bad argument #2 (invalid parent class name %s)", parenttname); lua_setmetatable(L, -2); } } /******** root-metatable ********/ /* id is the pointer on the metatable registry[id] = root-metatable, so try to see if it exists */ lua_pushlightuserdata(L, (void*)id); /* id */ lua_rawget(L, LUA_REGISTRYINDEX); /* not existing? we create a new one! */ if(lua_isnil(L, -1)) { lua_pop(L, 1); /* remove nil on stack */ lua_newtable(L); /* __index handling */ lua_pushcfunction(L, luaT_rmt__index); lua_setfield(L, -2, "__index"); /* __newindex handling */ lua_pushcfunction(L, luaT_rmt__newindex); lua_setfield(L, -2, "__newindex"); /* __metatable field (point on the metaclass) */ lua_pushvalue(L, -2); lua_setfield(L, -2, "__metatable"); /* __typename contains the typename */ lua_pushstring(L, tname); lua_setfield(L, -2, "__typename"); /* operators handling */ #define MT_ADD_OPERATOR(name) \ lua_pushcfunction(L, luaT_rmt__##name); \ lua_setfield(L, -2, "__" #name) MT_ADD_OPERATOR(tostring); MT_ADD_OPERATOR(add); MT_ADD_OPERATOR(sub); MT_ADD_OPERATOR(mul); MT_ADD_OPERATOR(div); MT_ADD_OPERATOR(mod); MT_ADD_OPERATOR(pow); MT_ADD_OPERATOR(unm); MT_ADD_OPERATOR(concat); MT_ADD_OPERATOR(len); MT_ADD_OPERATOR(eq); MT_ADD_OPERATOR(lt); MT_ADD_OPERATOR(le); MT_ADD_OPERATOR(call); /* assign the metaclass as metatable... */ lua_pushvalue(L, -2); lua_setmetatable(L, -2); /* id is the pointer on the metatable set registry[id] = root-metatable */ lua_pushlightuserdata(L, (void*)id); /* id */ lua_pushvalue(L, -2); /* metatable */ lua_rawset(L, LUA_REGISTRYINDEX); /* registry[id] = metatable */ } /* ok, so now we have the root-metatable on the stack */ /* register the destructor function */ if(!lua_isnoneornil(L, 4)) { /* does it exists already? */ lua_pushstring(L, "__gc"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_pushstring(L, "__gc"); lua_pushvalue(L, 4); lua_rawset(L, -3); } else luaL_error(L, "%s has been already assigned a destructor", tname); } /* register the factory function */ if(!lua_isnoneornil(L, 5)) { /* does it exists already? */ lua_pushstring(L, "__factory"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_pushstring(L, "__factory"); lua_pushvalue(L, 5); lua_rawset(L, -3); } else luaL_error(L, "%s has been already assigned a factory", tname); } /******** Constructor table and metatable ********/ lua_pushstring(L, "__constructor"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_newtable(L); /* fancy table */ lua_newtable(L); /* fancy metatable */ lua_pushvalue(L, -4); /* metaclass */ lua_setfield(L, -2, "__index"); /* so we can get the methods */ lua_pushcfunction(L, luaT_cmt__newindex); lua_setfield(L, -2, "__newindex"); /* so we cannot messup */ lua_pushcfunction(L, luaT_cmt__call); lua_setfield(L, -2, "__call"); /* so we can create */ lua_pushvalue(L, -4); lua_setfield(L, -2, "__metatable"); /* redirect to metatable with methods */ lua_setmetatable(L, -2); /* metatable is ... the fancy metatable */ /* set root-metatable[__constructor] = constructor-metatable */ lua_pushstring(L, "__constructor"); lua_pushvalue(L, -2); lua_rawset(L, -4); } /* register the constructor function */ if(!lua_isnoneornil(L, 3)) { /* get constructor metatable */ lua_getmetatable(L, -1); /* does it exists already? */ lua_pushstring(L, "__new"); lua_rawget(L, -2); if(lua_isnil(L, -1)) { lua_pop(L, 1); /* pop nil */ lua_pushstring(L, "__new"); lua_pushvalue(L, 3); lua_rawset(L, -3); } else luaL_error(L, "%s has been already assigned a constructor", tname); /* pop constructor metatable */ lua_pop(L, 1); } lua_setfield(L, 6, luaT_classrootname(tname)); /* module.name = constructor-metatable */ lua_pop(L, 1); /* pop the root-metatable */ return 1; /* returns the metaclass */ }
ItemDefinition read_item_definition(lua_State* L,int index, ItemDefinition default_def) { if(index < 0) index = lua_gettop(L) + 1 + index; // Read the item definition ItemDefinition def = default_def; def.type = (ItemType)getenumfield(L, index, "type", es_ItemType, ITEM_NONE); getstringfield(L, index, "name", def.name); getstringfield(L, index, "description", def.description); getstringfield(L, index, "inventory_image", def.inventory_image); getstringfield(L, index, "wield_image", def.wield_image); lua_getfield(L, index, "wield_scale"); if(lua_istable(L, -1)){ def.wield_scale = check_v3f(L, -1); } lua_pop(L, 1); def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max); if(def.stack_max == 0) def.stack_max = 1; lua_getfield(L, index, "on_use"); def.usable = lua_isfunction(L, -1); lua_pop(L, 1); getboolfield(L, index, "liquids_pointable", def.liquids_pointable); warn_if_field_exists(L, index, "tool_digging_properties", "deprecated: use tool_capabilities"); lua_getfield(L, index, "tool_capabilities"); if(lua_istable(L, -1)){ def.tool_capabilities = new ToolCapabilities( read_tool_capabilities(L, -1)); } // If name is "" (hand), ensure there are ToolCapabilities // because it will be looked up there whenever any other item has // no ToolCapabilities if(def.name == "" && def.tool_capabilities == NULL){ def.tool_capabilities = new ToolCapabilities(); } lua_getfield(L, index, "groups"); read_groups(L, -1, def.groups); lua_pop(L, 1); lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "place"); read_soundspec(L, -1, def.sound_place); lua_pop(L, 1); } lua_pop(L, 1); def.range = getfloatfield_default(L, index, "range", def.range); // Client shall immediately place this node when player places the item. // Server will update the precise end result a moment later. // "" = no prediction getstringfield(L, index, "node_placement_prediction", def.node_placement_prediction); return def; }
int m_isfunction (lua_State *L, int index) { return lua_isfunction(L, index); }
/* args: const char *className const char *methodName LUA_TABLE args const char *sig */ int CCLuaJavaBridge::callJavaStaticMethod(lua_State *L) { if (!lua_isstring(L, -4) || !lua_isstring(L, -3) || !lua_istable(L, -2) || !lua_isstring(L, -1)) { lua_pushboolean(L, 0); lua_pushinteger(L, LUAJ_ERR_INVALID_SIGNATURES); return 2; } LOGD("%s", "CCLuaJavaBridge::callJavaStaticMethod(lua_State *L)"); const char *className = lua_tostring(L, -4); const char *methodName = lua_tostring(L, -3); const char *methodSig = lua_tostring(L, -1); CallInfo call(className, methodName, methodSig); if (!call.isValid()) { LOGD("CCLuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") CHECK FAILURE, ERROR CODE: %d", className, methodName, methodSig, call.getErrorCode()); lua_pushboolean(L, 0); lua_pushinteger(L, call.getErrorCode()); return 2; } // check args lua_pop(L, 1); /* L: args */ int count = fetchArrayElements(L, -1); /* L: args e1 e2 e3 e4 ... */ jvalue *args = NULL; if (count > 0) { args = new jvalue[count]; for (int i = count - 1; i >= 0; --i) { int index = -count + i; switch (call.argumentTypeAtIndex(i)) { case TypeInteger: if (lua_isfunction(L, -1)) { args[i].i = retainLuaFunction(L, -1, NULL); } else { args[i].i = (int)lua_tonumber(L, -1); } break; case TypeFloat: args[i].f = lua_tonumber(L, -1); break; case TypeBoolean: args[i].z = lua_toboolean(L, -1) != 0 ? JNI_TRUE : JNI_FALSE; break; case TypeVector: args[i].l = CCLuaJavaBridge::checkVector(L); break; case TypeMap: args[i].l = CCLuaJavaBridge::checkHashMap(L); break; case TypeArrayList: args[i].l = CCLuaJavaBridge::checkArrayList(L); break; case TypeString: default: args[i].l = call.getEnv()->NewStringUTF(lua_tostring(L, -1)); break; } lua_pop(L, 1); } //lua_pop(L, count); /* L: args */ } bool success = args ? call.executeWithArgs(args) : call.execute(); if (args) delete []args; if (!success) { LOGD("CCLuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") EXECUTE FAILURE, ERROR CODE: %d", className, methodName, methodSig, call.getErrorCode()); lua_pushboolean(L, 0); lua_pushinteger(L, call.getErrorCode()); return 2; } LOGD("CCLuaJavaBridge::callJavaStaticMethod(\"%s\", \"%s\", args, \"%s\") SUCCESS", className, methodName, methodSig); lua_pushboolean(L, 1); return 1 + call.pushReturnValue(L); }
// Lua: server:listen(port, addr, function(c)), socket:listen(port, addr) int net_listen( lua_State *L ) { lnet_userdata *ud = net_get_udata(L); if (!ud || ud->type == TYPE_TCP_CLIENT) return luaL_error(L, "invalid user data"); if (ud->pcb) return luaL_error(L, "already listening"); int stack = 2; uint16_t port = 0; const char *domain = "0.0.0.0"; if (lua_isnumber(L, stack)) port = lua_tointeger(L, stack++); if (lua_isstring(L, stack)) { size_t dl = 0; domain = luaL_checklstring(L, stack++, &dl); } ip_addr_t addr; if (!ipaddr_aton(domain, &addr)) return luaL_error(L, "invalid IP address"); if (ud->type == TYPE_TCP_SERVER) { if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) { lua_pushvalue(L, stack++); luaL_unref(L, LUA_REGISTRYINDEX, ud->server.cb_accept_ref); ud->server.cb_accept_ref = luaL_ref(L, LUA_REGISTRYINDEX); } else { return luaL_error(L, "need callback"); } } err_t err = ERR_OK; switch (ud->type) { case TYPE_TCP_SERVER: ud->tcp_pcb = tcp_new(); if (!ud->tcp_pcb) return luaL_error(L, "cannot allocate PCB"); ud->tcp_pcb->so_options |= SOF_REUSEADDR; err = tcp_bind(ud->tcp_pcb, &addr, port); if (err == ERR_OK) { tcp_arg(ud->tcp_pcb, ud); struct tcp_pcb *pcb = tcp_listen(ud->tcp_pcb); if (!pcb) { err = ERR_MEM; } else { ud->tcp_pcb = pcb; tcp_accept(ud->tcp_pcb, net_accept_cb); } } break; case TYPE_UDP_SOCKET: ud->udp_pcb = udp_new(); if (!ud->udp_pcb) return luaL_error(L, "cannot allocate PCB"); udp_recv(ud->udp_pcb, net_udp_recv_cb, ud); err = udp_bind(ud->udp_pcb, &addr, port); break; } if (err != ERR_OK) { switch (ud->type) { case TYPE_TCP_SERVER: tcp_close(ud->tcp_pcb); ud->tcp_pcb = NULL; break; case TYPE_UDP_SOCKET: udp_remove(ud->udp_pcb); ud->udp_pcb = NULL; break; } return lwip_lua_checkerr(L, err); } if (ud->self_ref == LUA_NOREF) { lua_pushvalue(L, 1); ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); } return 0; }
int LuaStack::executeFunctionReturnArray(int handler,int numArgs,int numResults,__Array& resultArray) { int top = lua_gettop(_state); if (pushFunctionByHandler(handler)) /* L: ... arg1 arg2 ... func */ { if (numArgs > 0) { lua_insert(_state, -(numArgs + 1)); /* L: ... func arg1 arg2 ... */ } int functionIndex = -(numArgs + 1); if (!lua_isfunction(_state, functionIndex)) { CCLOG("value at stack [%d] is not function", functionIndex); lua_pop(_state, numArgs + 1); // remove function and arguments lua_settop(_state,top); return 0; } int traceback = 0; lua_getglobal(_state, "__G__TRACKBACK__"); /* L: ... func arg1 arg2 ... G */ if (!lua_isfunction(_state, -1)) { lua_pop(_state, 1); /* L: ... func arg1 arg2 ... */ } else { lua_insert(_state, functionIndex - 1); /* L: ... G func arg1 arg2 ... */ traceback = functionIndex - 1; } int error = 0; ++_callFromLua; error = lua_pcall(_state, numArgs, numResults, traceback); /* L: ... [G] ret1 ret2 ... retResults*/ --_callFromLua; if (error) { if (traceback == 0) { CCLOG("[LUA ERROR] %s", lua_tostring(_state, - 1)); /* L: ... error */ lua_pop(_state, 1); // remove error message from stack } else /* L: ... G error */ { lua_pop(_state, 2); // remove __G__TRACKBACK__ and error message from stack } lua_settop(_state,top); return 0; } // get return value,don't pass LUA_MULTRET to numResults, if (numResults <= 0) { lua_settop(_state,top); return 0; } for (int i = 0 ; i < numResults; i++) { if (lua_type(_state, -1) == LUA_TBOOLEAN) { bool value = lua_toboolean(_state, -1); resultArray.addObject(Bool::create(value)) ; }else if (lua_type(_state, -1) == LUA_TNUMBER) { double value = lua_tonumber(_state, -1); resultArray.addObject(Double::create(value)); }else if (lua_type(_state, -1) == LUA_TSTRING) { const char* value = lua_tostring(_state, -1); resultArray.addObject(String::create(value)); }else{ resultArray.addObject(static_cast<Ref*>(tolua_tousertype(_state, -1, nullptr))); } // remove return value from stack lua_pop(_state, 1); /* L: ... [G] ret1 ret2 ... ret*/ } /* L: ... [G]*/ if (traceback) { lua_pop(_state, 1); // remove __G__TRACKBACK__ from stack /* L: ... */ } } lua_settop(_state,top); return 1; }
// Lua: client:send(data, function(c)), socket:send(port, ip, data, function(s)) int net_send( lua_State *L ) { lnet_userdata *ud = net_get_udata(L); if (!ud || ud->type == TYPE_TCP_SERVER) return luaL_error(L, "invalid user data"); ip_addr_t addr; uint16_t port; const char *data; size_t datalen = 0; int stack = 2; if (ud->type == TYPE_UDP_SOCKET) { size_t dl = 0; port = luaL_checkinteger(L, stack++); if (port == 0) return luaL_error(L, "need port"); const char *domain = luaL_checklstring(L, stack++, &dl); if (!domain) return luaL_error(L, "need IP address"); if (!ipaddr_aton(domain, &addr)) return luaL_error(L, "invalid IP address"); } data = luaL_checklstring(L, stack++, &datalen); if (!data || datalen == 0) return luaL_error(L, "no data to send"); if (lua_isfunction(L, stack) || lua_islightfunction(L, stack)) { lua_pushvalue(L, stack++); luaL_unref(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); ud->client.cb_sent_ref = luaL_ref(L, LUA_REGISTRYINDEX); } if (ud->type == TYPE_UDP_SOCKET && !ud->pcb) { ud->udp_pcb = udp_new(); if (!ud->udp_pcb) return luaL_error(L, "cannot allocate PCB"); udp_recv(ud->udp_pcb, net_udp_recv_cb, ud); ip_addr_t laddr = {0}; err_t err = udp_bind(ud->udp_pcb, &laddr, 0); if (err != ERR_OK) { udp_remove(ud->udp_pcb); ud->udp_pcb = NULL; return lwip_lua_checkerr(L, err); } if (ud->self_ref == LUA_NOREF) { lua_pushvalue(L, 1); ud->self_ref = luaL_ref(L, LUA_REGISTRYINDEX); } } if (!ud->pcb || ud->self_ref == LUA_NOREF) return luaL_error(L, "not connected"); err_t err; if (ud->type == TYPE_UDP_SOCKET) { struct pbuf *pb = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM); if (!pb) return luaL_error(L, "cannot allocate message buffer"); pbuf_take(pb, data, datalen); err = udp_sendto(ud->udp_pcb, pb, &addr, port); pbuf_free(pb); if (ud->client.cb_sent_ref != LUA_NOREF) { lua_rawgeti(L, LUA_REGISTRYINDEX, ud->client.cb_sent_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, ud->self_ref); lua_call(L, 1, 0); } } else if (ud->type == TYPE_TCP_CLIENT) { err = tcp_write(ud->tcp_pcb, data, datalen, TCP_WRITE_FLAG_COPY); } return lwip_lua_checkerr(L, err); }
int CCLuaEngine::executeFunctionByRefID(int nHandler, int numArgs) { lua_pushstring(m_state, TOLUA_REFID_FUNC_MAPPING); lua_rawget(m_state, LUA_REGISTRYINDEX); /* stack: ... refid_func */ lua_pushinteger(m_state, nHandler); /* stack: ... refid_func refid */ lua_rawget(m_state, -2); /* stack: ... refid_func func */ if (!lua_isfunction(m_state, -1)) { CCLOG("[LUA ERROR] function refid '%d' does not reference a Lua function", nHandler); lua_pop(m_state, 2 + numArgs); return 0; } if (numArgs > 0) { // [a1] [a2] refid_func func // -4 -3 -2 -1 // [a1] [a2] refid_func func [a1] // -5 -4 -3 -2 -1 int lo = -2 - numArgs; for (int i = 0; i < numArgs; i++) { tolua_pushvalue(m_state, lo); /* stack: ... refid_func func (...) */ } } int error = 0; try { error = lua_pcall(m_state, numArgs, 1, 0); /* stack: ... refid_func ret */ } catch (exception& e) { CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ exception: %s", nHandler, e.what()); lua_settop(m_state, 0); return 0; } catch (...) { CCLOG("[LUA ERROR] lua_pcall(%d) catch C++ unknown exception.", nHandler); lua_settop(m_state, 0); return 0; } if (error) { CCLOG("[LUA ERROR] %s", lua_tostring(m_state, - 1)); lua_pop(m_state, 2 + numArgs); // clean error message return 0; } // get return value int ret = 0; if (lua_isnumber(m_state, -1)) { ret = lua_tointeger(m_state, -1); } else if (lua_isboolean(m_state, -1)) { ret = lua_toboolean(m_state, -1); } lua_pop(m_state, 2 + numArgs); return ret; }
int serialize_data(lua_sandbox* lsb, int index, output_data* output) { output->m_pos = 0; switch (lua_type(lsb->m_lua, index)) { case LUA_TNUMBER: if (dynamic_snprintf(output, "%0.9g", lua_tonumber(lsb->m_lua, index))) { return 1; } break; case LUA_TSTRING: // The stack is cleaned up on failure by preserve_global_data // but for clarity it is incrementally cleaned up anyway. lua_checkstack(lsb->m_lua, 4); lua_getglobal(lsb->m_lua, "string"); if (!lua_istable(lsb->m_lua, -1)) { snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data cannot access the string table"); lua_pop(lsb->m_lua, 1); // Remove bogus string table. return 1; } lua_getfield(lsb->m_lua, -1, "format"); if (!lua_isfunction(lsb->m_lua, -1)) { snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data cannot access the string format function"); lua_pop(lsb->m_lua, 2); // Remove the bogus format function and // string table. return 1; } lua_pushstring(lsb->m_lua, "%q"); lua_pushvalue(lsb->m_lua, index - 3); if (lua_pcall(lsb->m_lua, 2, 1, 0) == 0) { if (dynamic_snprintf(output, "%s", lua_tostring(lsb->m_lua, -1))) { lua_pop(lsb->m_lua, 1); // Remove the string table. return 1; } } else { snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data '%s'", lua_tostring(lsb->m_lua, -1)); lua_pop(lsb->m_lua, 2); // Remove the error message and the string // table. return 1; } lua_pop(lsb->m_lua, 2); // Remove the pcall result and the string table. break; case LUA_TNIL: if (dynamic_snprintf(output, "nil")) { return 1; } break; case LUA_TBOOLEAN: if (dynamic_snprintf(output, "%s", lua_toboolean(lsb->m_lua, index) ? "true" : "false")) { return 1; } break; default: snprintf(lsb->m_error_message, ERROR_SIZE, "serialize_data cannot preserve type '%s'", lua_typename(lsb->m_lua, lua_type(lsb->m_lua, index))); return 1; } return 0; }
/// Wrapper around lua_isfunction. /// /// \param index The second parameter to lua_isfunction. /// /// \return The return value of lua_isfunction. bool lutok::state::is_function(const int index) { return lua_isfunction(_pimpl->lua_state, index); }
void Script::callFunction(const char *func,const char *sig,...) { va_list vl; int narg,nres; va_start(vl,sig); lua_getglobal(mThreadState,func); if(lua_isfunction(mThreadState,-1)) { narg = 0; while(*sig) { switch (*sig++) { case 'd': lua_pushnumber(mThreadState,va_arg(vl,double)); break; case 'i': lua_pushnumber(mThreadState,va_arg(vl,int)); break; case 's': lua_pushstring(mThreadState,va_arg(vl,char *)); break; case '>': goto endwhile; break; default: break; } narg++; luaL_checkstack(mThreadState,1,"too many arguments"); } endwhile: nres = strlen(sig); if(lua_pcall(mThreadState,narg,nres,0) != 0) { _formatError(); gLogger->logMsgF("ScriptingEngine::callFunction Runtime Error: %s",MSG_NORMAL,mLastError); } nres = -nres; while(*sig) { switch (*sig++) { case 'd': { if(!lua_isnumber(mThreadState,nres)) { _formatError(); gLogger->logMsgF("ScriptingEngine::callFunction wrong result type: %s",MSG_NORMAL,mLastError); } *va_arg(vl,double *) = lua_tonumber(mThreadState,nres); } break; case 'i': { if(!lua_isnumber(mThreadState,nres)) { _formatError(); gLogger->logMsgF("ScriptingEngine::callFunction wrong result type: %s",MSG_NORMAL,mLastError); } *va_arg(vl,int*) = (int)lua_tonumber(mThreadState,nres); } break; case 's': { if(!lua_isstring(mThreadState,nres)) { _formatError(); gLogger->logMsgF("ScriptingEngine::callFunction wrong result type: %s",MSG_NORMAL,mLastError); } *va_arg(vl,const char **) = lua_tostring(mThreadState,nres); } break; default: { _formatError(); gLogger->logMsgF("ScriptingEngine::callFunction invalid option: %s",MSG_NORMAL,mLastError); } break; } nres++; } } va_end(vl); }
int dissect_lua(tvbuff_t* tvb, packet_info* pinfo, proto_tree* tree) { int consumed_bytes = tvb->length; lua_pinfo = pinfo; lua_tvb = tvb; lua_tree = g_malloc(sizeof(struct _wslua_treeitem)); lua_tree->tree = tree; lua_tree->item = proto_tree_add_text(tree,tvb,0,0,"lua fake item"); lua_tree->expired = FALSE; PROTO_ITEM_SET_HIDDEN(lua_tree->item); /* * almost equivalent to Lua: * dissectors[current_proto](tvb,pinfo,tree) */ lua_settop(L,0); lua_rawgeti(L, LUA_REGISTRYINDEX, lua_dissectors_table_ref); lua_pushstring(L, pinfo->current_proto); lua_gettable(L, -2); lua_remove(L,1); if (lua_isfunction(L,1)) { push_Tvb(L,tvb); push_Pinfo(L,pinfo); push_TreeItem(L,lua_tree); if ( lua_pcall(L,3,1,0) ) { const gchar* error = lua_tostring(L,-1); proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: %s",error); expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_ERROR ,"Lua Error"); } else { /* if the Lua dissector reported the consumed bytes, pass it to our caller */ if (lua_isnumber(L, -1)) { /* we got the consumed bytes or the missing bytes as a negative number */ consumed_bytes = (int) lua_tonumber(L, -1); lua_pop(L, 1); } } } else { proto_item* pi = proto_tree_add_text(tree,tvb,0,0,"Lua Error: did not find the %s dissector" " in the dissectors table",pinfo->current_proto); expert_add_info_format(pinfo, pi, PI_UNDECODED, PI_ERROR ,"Lua Error"); } register_frame_end_routine(lua_frame_end); lua_pinfo = NULL; lua_tree = NULL; lua_tvb = NULL; return consumed_bytes; }
ngx_int_t ngx_http_lua_content_handler_file(ngx_http_request_t *r) { lua_State *L; ngx_int_t rc; u_char *script_path; ngx_http_lua_main_conf_t *lmcf; ngx_http_lua_loc_conf_t *llcf; char *err; ngx_str_t eval_src; llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); if (ngx_http_complex_value(r, &llcf->content_src, &eval_src) != NGX_OK) { return NGX_ERROR; } script_path = ngx_http_lua_rebase_path(r->pool, eval_src.data, eval_src.len); if (script_path == NULL) { return NGX_ERROR; } lmcf = ngx_http_get_module_main_conf(r, ngx_http_lua_module); L = lmcf->lua; /* load Lua script file (w/ cache) sp = 1 */ rc = ngx_http_lua_cache_loadfile(L, script_path, llcf->content_src_key, &err, llcf->enable_code_cache ? 1 : 0); if (rc != NGX_OK) { if (err == NULL) { err = "unknown error"; } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "Failed to load Lua inlined code: %s", err); return NGX_HTTP_INTERNAL_SERVER_ERROR; } /* make sure we have a valid code chunk */ assert(lua_isfunction(L, -1)); rc = ngx_http_lua_content_by_chunk(L, r); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } if (rc == NGX_DONE) { return NGX_DONE; } if (rc == NGX_AGAIN) { #if defined(nginx_version) && nginx_version >= 8011 r->main->count++; #endif return NGX_DONE; } return NGX_OK; }
int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_value, uint16 step) { *yield_value = 0; if (!f) { sprintf(pduel->strbuffer, "\"CallCoroutine\": attempt to call a null function"); handle_message(pduel, 1); params.clear(); return OPERATION_FAIL; } if (param_count != params.size()) { sprintf(pduel->strbuffer, "\"CallCoroutine\": incorrect parameter count"); handle_message(pduel, 1); params.clear(); return OPERATION_FAIL; } coroutine_map::iterator it; it = coroutines.find(f); lua_State* rthread; if (it == coroutines.end()) { rthread = lua_newthread(lua_state); function2value(rthread, f); if(!lua_isfunction(rthread, -1)) { sprintf(pduel->strbuffer, "\"CallCoroutine\": attempt to call an error function"); handle_message(pduel, 1); params.clear(); return OPERATION_FAIL; } call_depth++; coroutines.insert(make_pair(f, rthread)); } else { rthread = it->second; if(step == 0) { sprintf(pduel->strbuffer, "recursive event trigger detected."); handle_message(pduel, 1); params.clear(); call_depth--; if(call_depth == 0) pduel->release_script_group(); return OPERATION_FAIL; } } push_param(rthread, true); current_state = rthread; int32 result = lua_resume(rthread, 0, param_count); if (result == 0) { coroutines.erase(f); if(yield_value) *yield_value = lua_isboolean(rthread, -1) ? lua_toboolean(rthread, -1) : lua_tointeger(rthread, -1); current_state = lua_state; call_depth--; if(call_depth == 0) pduel->release_script_group(); return COROUTINE_FINISH; } else if (result == LUA_YIELD) { return COROUTINE_YIELD; } else { coroutines.erase(f); sprintf(pduel->strbuffer, lua_tostring(rthread, -1)); handle_message(pduel, 1); lua_pop(rthread, 1); current_state = lua_state; call_depth--; if(call_depth == 0) pduel->release_script_group(); return COROUTINE_ERROR; } }
lua_State *script_cache_get_script(server *srv, connection *con, script_cache *cache, buffer *name) { size_t i; script *sc = NULL; stat_cache_entry *sce; for (i = 0; i < cache->used; i++) { sc = cache->ptr[i]; if (buffer_is_equal(name, sc->name)) { sc->last_used = time(NULL); /* oops, the script failed last time */ if (lua_gettop(sc->L) == 0) break; if (HANDLER_ERROR == stat_cache_get_entry(srv, con, sc->name, &sce)) { lua_pop(sc->L, 1); /* pop the old function */ break; } if (!buffer_is_equal(sce->etag, sc->etag)) { /* the etag is outdated, reload the function */ lua_pop(sc->L, 1); break; } assert(lua_isfunction(sc->L, -1)); lua_pushvalue(sc->L, -1); /* copy the function-reference */ return sc->L; } sc = NULL; } /* if the script was script already loaded but either got changed or * failed to load last time */ if (sc == NULL) { sc = script_init(); if (cache->size == 0) { cache->size = 16; cache->ptr = malloc(cache->size * sizeof(*(cache->ptr))); } else if (cache->used == cache->size) { cache->size += 16; cache->ptr = realloc(cache->ptr, cache->size * sizeof(*(cache->ptr))); } cache->ptr[cache->used++] = sc; buffer_copy_string_buffer(sc->name, name); sc->L = luaL_newstate(); luaL_openlibs(sc->L); } sc->last_used = time(NULL); if (0 != luaL_loadfile(sc->L, name->ptr)) { /* oops, an error, return it */ return sc->L; } if (HANDLER_GO_ON == stat_cache_get_entry(srv, con, sc->name, &sce)) { buffer_copy_string_buffer(sc->etag, sce->etag); } /** * pcall() needs the function on the stack * * as pcall() will pop the script from the stack when done, we have to * duplicate it here */ assert(lua_isfunction(sc->L, -1)); lua_pushvalue(sc->L, -1); /* copy the function-reference */ return sc->L; }