static ngx_int_t ngx_http_lua_balancer_by_chunk(lua_State *L, ngx_http_request_t *r) { u_char *err_msg; size_t len; ngx_int_t rc; ngx_http_lua_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } } else { dd("reset ctx"); ngx_http_lua_reset_ctx(r, L, ctx); } ctx->context = NGX_HTTP_LUA_CONTEXT_BALANCER; /* init nginx context in Lua VM */ ngx_http_lua_set_req(L, r); ngx_http_lua_create_new_globals_table(L, 0 /* narr */, 1 /* nrec */); /* {{{ make new env inheriting main thread's globals table */ lua_createtable(L, 0, 1 /* nrec */); /* the metatable for the new env */ ngx_http_lua_get_globals_table(L); lua_setfield(L, -2, "__index"); lua_setmetatable(L, -2); /* setmetatable({}, {__index = _G}) */ /* }}} */ lua_setfenv(L, -2); /* set new running env for the code closure */ lua_pushcfunction(L, ngx_http_lua_traceback); lua_insert(L, 1); /* put it under chunk and args */ /* protected call user code */ rc = lua_pcall(L, 0, 1, 1); lua_remove(L, 1); /* remove traceback function */ dd("rc == %d", (int) rc); if (rc != 0) { /* error occured when running loaded code */ err_msg = (u_char *) lua_tolstring(L, -1, &len); if (err_msg == NULL) { err_msg = (u_char *) "unknown reason"; len = sizeof("unknown reason") - 1; } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to run balancer_by_lua*: %*s", len, err_msg); lua_settop(L, 0); /* clear remaining elems on stack */ return NGX_ERROR; } lua_settop(L, 0); /* clear remaining elems on stack */ return rc; }
/* Class index function * If the object is a userdata (ie, an object), it searches the field in * the alternative table stored in the corresponding "ubox" table. */ static int class_index_event (lua_State* L) { int t = lua_type(L,1); if (t == LUA_TUSERDATA) { /* Access alternative table */ #ifdef LUA_VERSION_NUM /* new macro on version 5.1 */ lua_getfenv(L,1); if (!lua_rawequal(L, -1, TOLUA_NOPEER)) { lua_pushvalue(L, 2); /* key */ lua_gettable(L, -2); /* on lua 5.1, we trade the "tolua_peers" lookup for a gettable call */ if (!lua_isnil(L, -1)) return 1; }; #else lua_pushstring(L,"tolua_peers"); lua_rawget(L,LUA_REGISTRYINDEX); /* stack: obj key ubox */ lua_pushvalue(L,1); lua_rawget(L,-2); /* stack: obj key ubox ubox[u] */ if (lua_istable(L,-1)) { lua_pushvalue(L,2); /* key */ lua_rawget(L,-2); /* stack: obj key ubox ubox[u] value */ if (!lua_isnil(L,-1)) return 1; } #endif lua_settop(L,2); /* stack: obj key */ /* Try metatables */ lua_pushvalue(L,1); /* stack: obj key obj */ while (lua_getmetatable(L,-1)) { /* stack: obj key obj mt */ lua_remove(L,-2); /* stack: obj key mt */ if (lua_isnumber(L,2)) /* check if key is a numeric value */ { /* try operator[] */ lua_pushstring(L,".geti"); lua_rawget(L,-2); /* stack: obj key mt func */ if (lua_isfunction(L,-1)) { lua_pushvalue(L,1); lua_pushvalue(L,2); lua_call(L,2,1); return 1; } } else { lua_pushvalue(L,2); /* stack: obj key mt key */ lua_rawget(L,-2); /* stack: obj key mt value */ if (!lua_isnil(L,-1)) return 1; else lua_pop(L,1); /* try C/C++ variable */ lua_pushstring(L,".get"); lua_rawget(L,-2); /* stack: obj key mt tget */ if (lua_istable(L,-1)) { lua_pushvalue(L,2); lua_rawget(L,-2); /* stack: obj key mt value */ if (lua_iscfunction(L,-1)) { lua_pushvalue(L,1); lua_pushvalue(L,2); lua_call(L,2,1); return 1; } else if (lua_istable(L,-1)) { /* deal with array: create table to be returned and cache it in ubox */ void* u = *((void**)lua_touserdata(L,1)); lua_newtable(L); /* stack: obj key mt value table */ lua_pushstring(L,".self"); lua_pushlightuserdata(L,u); lua_rawset(L,-3); /* store usertype in ".self" */ lua_insert(L,-2); /* stack: obj key mt table value */ lua_setmetatable(L,-2); /* set stored value as metatable */ lua_pushvalue(L,-1); /* stack: obj key met table table */ lua_pushvalue(L,2); /* stack: obj key mt table table key */ lua_insert(L,-2); /* stack: obj key mt table key table */ storeatubox(L,1); /* stack: obj key mt table */ return 1; } } } lua_settop(L,3); } lua_pushnil(L); return 1; } else if (t== LUA_TTABLE) { module_index_event(L); return 1; } lua_pushnil(L); return 1; }
/*! * \brief Locate an extensions and optionally push the matching function on the * stack * * \param L the lua_State to use * \param context the context to look in * \param exten the extension to look up * \param priority the priority to check, '1' is the only valid priority * \param func the calling func, used to adjust matching behavior between, * match, canmatch, and matchmore * \param push_func whether or not to push the lua function for the given * extension onto the stack */ static int lua_find_extension(lua_State *L, const char *context, const char *exten, int priority, ast_switch_f *func, int push_func) { int context_table, context_order_table, i; ast_debug(2, "Looking up %s@%s:%i\n", exten, context, priority); if (priority != 1) return 0; /* load the 'extensions' table */ lua_getglobal(L, "extensions"); if (lua_isnil(L, -1)) { ast_log(LOG_ERROR, "Unable to find 'extensions' table in extensions.lua\n"); lua_pop(L, 1); return 0; } /* load the given context */ lua_getfield(L, -1, context); if (lua_isnil(L, -1)) { lua_pop(L, 2); return 0; } /* remove the extensions table */ lua_remove(L, -2); context_table = lua_gettop(L); /* load the extensions order table for this context */ lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); lua_getfield(L, -1, context); lua_remove(L, -2); /* remove the extensions order table */ context_order_table = lua_gettop(L); /* step through the extensions looking for a match */ for (i = 1; i < lua_objlen(L, context_order_table) + 1; i++) { int e_index, e_index_copy, match = 0; const char *e; lua_pushinteger(L, i); lua_gettable(L, context_order_table); e_index = lua_gettop(L); /* copy the key at the top of the stack for use later */ lua_pushvalue(L, -1); e_index_copy = lua_gettop(L); if (!(e = lua_tostring(L, e_index_copy))) { lua_pop(L, 2); continue; } /* make sure this is not the 'include' extension */ if (!strcasecmp(e, "include")) { lua_pop(L, 2); continue; } if (func == &matchmore) match = ast_extension_close(e, exten, E_MATCHMORE); else if (func == &canmatch) match = ast_extension_close(e, exten, E_CANMATCH); else match = ast_extension_match(e, exten); /* the extension matching functions return 0 on fail, 1 on * match, 2 on earlymatch */ if (!match) { /* pop the copy and the extension */ lua_pop(L, 2); continue; /* keep trying */ } if (func == &matchmore && match == 2) { /* We match an extension ending in '!'. The decision in * this case is final and counts as no match. */ lua_pop(L, 4); return 0; } /* remove the context table, the context order table, the * extension, and the extension copy (or replace the extension * with the corresponding function) */ if (push_func) { lua_pop(L, 1); /* pop the copy */ lua_gettable(L, context_table); lua_insert(L, -3); lua_pop(L, 2); } else { lua_pop(L, 4); } return 1; } /* load the includes for this context */ lua_getfield(L, context_table, "include"); if (lua_isnil(L, -1)) { lua_pop(L, 3); return 0; } /* remove the context and the order table*/ lua_remove(L, context_order_table); lua_remove(L, context_table); /* Now try any includes we have in this context */ for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { const char *c = lua_tostring(L, -1); if (!c) continue; if (lua_find_extension(L, c, exten, priority, func, push_func)) { /* remove the value, the key, and the includes table * from the stack. Leave the function behind if * necessary */ if (push_func) lua_insert(L, -4); lua_pop(L, 3); return 1; } } /* pop the includes table */ lua_pop(L, 1); return 0; }
/** * wifi.sta.config() * Description: * Set current Station configuration. * Note: If there are multiple APs with the same ssid, you can connect to a specific one by entering it's MAC address into the "bssid" field. * Syntax: * wifi.sta.getconfig(ssid, password) --Set STATION configuration, Auto-connect by default, Connects to any BSSID * wifi.sta.getconfig(ssid, password, Auto_connect) --Set STATION configuration, Auto-connect(0 or 1), Connects to any BSSID * wifi.sta.getconfig(ssid, password, bssid) --Set STATION configuration, Auto-connect by default, Connects to specific BSSID * wifi.sta.getconfig(ssid, password, Auto_connect, bssid) --Set STATION configuration, Auto-connect(0 or 1), Connects to specific BSSID * Parameters: * ssid: string which is less than 32 bytes. * Password: string which is less than 64 bytes. * Auto_connect: 0 (disable Auto-connect) or 1 (to enable Auto-connect). * bssid: MAC address of Access Point you would like to connect to. * Returns: * Nothing. * * Example: --Connect to Access Point automatically when in range wifi.sta.getconfig("myssid", "password") --Connect to Access Point, User decides when to connect/disconnect to/from AP wifi.sta.getconfig("myssid", "mypassword", 0) wifi.sta.connect() --do some wifi stuff wifi.sta.disconnect() --Connect to specific Access Point automatically when in range wifi.sta.getconfig("myssid", "mypassword", "12:34:56:78:90:12") --Connect to specific Access Point, User decides when to connect/disconnect to/from AP wifi.sta.getconfig("myssid", "mypassword", 0) wifi.sta.connect() --do some wifi stuff wifi.sta.disconnect() * */ static int wifi_station_config( lua_State* L ) { size_t sl, pl, ml; struct station_config sta_conf; int auto_connect=0; const char *ssid = luaL_checklstring( L, 1, &sl ); if (sl>32 || ssid == NULL) return luaL_error( L, "ssid:<32" ); const char *password = luaL_checklstring( L, 2, &pl ); if (pl!=0 && (pl<8 || pl>64) || password == NULL) return luaL_error( L, "pwd:0,8~64" ); if(lua_isnumber(L, 3)) { auto_connect=luaL_checkinteger( L, 3 );; if ( auto_connect != 0 && auto_connect != 1) return luaL_error( L, "wrong arg type" ); } else if (lua_isstring(L, 3)&& !(lua_isnumber(L, 3))) { lua_pushnil(L); lua_insert(L, 3); auto_connect=1; } else { if(lua_isnil(L, 3)) return luaL_error( L, "wrong arg type" ); auto_connect=1; } if(lua_isnumber(L, 4)) { sta_conf.bssid_set = 0; c_memset(sta_conf.bssid, 0, 6); } else { if (lua_isstring(L, 4)) { const char *macaddr = luaL_checklstring( L, 4, &ml ); if (ml!=17) return luaL_error( L, "MAC:FF:FF:FF:FF:FF:FF" ); c_memset(sta_conf.bssid, 0, 6); os_str2macaddr(sta_conf.bssid, macaddr); sta_conf.bssid_set = 1; } else { sta_conf.bssid_set = 0; c_memset(sta_conf.bssid, 0, 6); } } c_memset(sta_conf.ssid, 0, 32); c_memset(sta_conf.password, 0, 64); c_memcpy(sta_conf.ssid, ssid, sl); c_memcpy(sta_conf.password, password, pl); NODE_DBG(sta_conf.ssid); NODE_DBG(" %d\n", sl); NODE_DBG(sta_conf.password); NODE_DBG(" %d\n", pl); NODE_DBG(" %d\n", sta_conf.bssid_set); NODE_DBG( MACSTR, MAC2STR(sta_conf.bssid)); NODE_DBG("\n"); wifi_station_set_config(&sta_conf); wifi_station_disconnect(); if(auto_connect==0) { wifi_station_set_auto_connect(false); } else { wifi_station_set_auto_connect(true); wifi_station_connect(); } // station_check_connect(0); return 0; }
/* * Function used as a callback for all Lua functions passed through * get_as3_value_from_lua_stack() */ AS3_Val as3_lua_callback(void * data, AS3_Val args) { /* WARNING: Panic alert! Use L*_FN checkers here! */ SPAM(("as3_lua_callback(): begin")); AS3_Val res; LuaFunctionCallbackData * func_data = (LuaFunctionCallbackData *) data; int nargs = 0; int status = 0; int results_base = 0; lua_State * L = func_data->L; if (L == NULL) { /* TODO: Should we crash here? fatal_error("state expired"); / * Does not return * / */ sztrace("as3_lua_callback: state expired"); return AS3_Undefined(); } { /* A new scope for LCALL to work (C89 conformance) */ LCALL(L, stack); /* TODO: Cache that with lua_ref, it is faster */ lua_getfield(L, LUA_REGISTRYINDEX, AS3LUA_CALLBACKS); /* TODO: Assert we have a table here */ lua_rawgeti(L, -1, func_data->ref); /* push stored function */ if (lua_istable(L, -1) == 0) /* Probably nil */ { lua_pop(L, 1); /* Pop bad callback table */ LCHECK_FN(L, stack, 0, fatal_error); fatal_error("function callback not found"); /* Does not return */ } lua_rawgeti(L, -1, AS3LUA_CBFNINDEX); /* push stored callback function */ #ifdef DO_SPAM { SPAM(("as3_lua_callback(): AS3 arguments")); AS3_Val a = AS3_CallS("join", args, AS3_Undefined()); AS3_Trace(a); SAFE_RELEASE(a); } #endif /* DO_SPAM */ /* TODO: Assert we have Lua function (or other callable object) on the top of the stack */ LCHECK_FN(L, stack, 2 + 1, fatal_error); nargs = push_as3_array_to_lua_stack(L, args); /* push arguments */ #ifdef DO_SPAM /* TODO: Remove */ lua_pushcfunction(L, as3_trace); dump_lua_stack(L, LBASE(L, stack) + 2 + 1); lua_pushliteral(L, "ARGUMENTS"); lua_pushnumber(L, nargs); lua_call(L, 3, 0); #endif /* DO_SPAM */ LCHECK_FN(L, stack, 2 + 1 + nargs, fatal_error); results_base = LBASE(L, stack) + 2; status = do_pcall_with_traceback(L, nargs, LUA_MULTRET); if (status != 0) { const char * msg = NULL; LCHECK_FN(L, stack, 2 + 1, fatal_error); /* Tables and error message */ lua_remove(L, -2); /* Remove AS3LUA_CALLBACKS table */ lua_remove(L, -2); /* Remove holder table */ LCHECK_FN(L, stack, 1, fatal_error); /* Only error message */ /* Error message is on stack */ /* NOTE: It is not necessary string! If we want to preserve its type, see lua_DoString. */ if (lua_tostring(L, -1) == NULL) { lua_pop(L, 1); lua_pushliteral(L, "(non-string)"); } LCHECK_FN(L, stack, 1, fatal_error); lua_pushliteral(L, "Error in Lua callback:\n"); lua_insert(L, -2); LCHECK_FN(L, stack, 2, fatal_error); lua_concat(L, 2); LCHECK_FN(L, stack, 1, fatal_error); sztrace((char *)lua_tostring(L, -1)); /* TODO: ?! */ /* lua_error(L); */ msg = lua_tostring(L, -1); lua_pop(L, 1); /* fatal_error(msg); / * Does not return * / */ } /* Process results */ #ifdef DO_SPAM /* TODO: Remove */ /* lua_pushcfunction(L, as3_trace); lua_pushliteral(L, "STACK"); dump_lua_stack(L, results_base); lua_call(L, 2, 0); */ #endif /* DO_SPAM */ res = create_as3_value_from_lua_stack(L, results_base + 1, LTOP(L, stack), TRUE); #ifdef DO_SPAM SPAM(("as3_lua_callback() result type")); AS3_Trace(AS3_Call(getQualifiedClassName_method, NULL, AS3_Array("AS3ValType", res))); #endif /* DO_SPAM */ lua_settop(L, LBASE(L, stack)); /* Cleanup results and two holder tables */ SPAM(("as3_lua_callback(): end")); return res; } /* Unreachable */ }
static void ngx_http_lua_timer_handler(ngx_event_t *ev) { int n; lua_State *L; ngx_int_t rc; ngx_log_t *log; ngx_connection_t *c = NULL, *saved_c = NULL; ngx_http_request_t *r = NULL; ngx_http_lua_ctx_t *ctx; ngx_http_cleanup_t *cln; ngx_pool_cleanup_t *pcln; ngx_http_log_ctx_t *logctx; ngx_http_lua_timer_ctx_t tctx; ngx_http_lua_main_conf_t *lmcf; ngx_http_core_loc_conf_t *clcf; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "lua ngx.timer expired"); ngx_memcpy(&tctx, ev->data, sizeof(ngx_http_lua_timer_ctx_t)); ngx_free(ev); ev = NULL; lmcf = tctx.lmcf; lmcf->pending_timers--; if (lmcf->running_timers >= lmcf->max_running_timers) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "%i lua_max_running_timers are not enough", lmcf->max_running_timers); goto abort; } /* create the fake connection (we temporarily use a valid fd (0) to make ngx_get_connection happy) */ if (ngx_cycle->files) { saved_c = ngx_cycle->files[0]; } c = ngx_get_connection(0, ngx_cycle->log); if (ngx_cycle->files) { ngx_cycle->files[0] = saved_c; } if (c == NULL) { goto abort; } c->fd = (ngx_socket_t) -1; c->pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, c->log); if (c->pool == NULL) { goto abort; } log = ngx_pcalloc(c->pool, sizeof(ngx_log_t)); if (log == NULL) { goto abort; } logctx = ngx_palloc(c->pool, sizeof(ngx_http_log_ctx_t)); if (logctx == NULL) { goto abort; } dd("c pool allocated: %d", (int) (sizeof(ngx_log_t) + sizeof(ngx_http_log_ctx_t) + sizeof(ngx_http_request_t))); logctx->connection = c; logctx->request = NULL; logctx->current_request = NULL; c->log = log; c->log->connection = c->number; c->log->handler = ngx_http_lua_log_timer_error; c->log->data = logctx; c->log->action = NULL; c->log_error = NGX_ERROR_INFO; #if 0 c->buffer = ngx_create_temp_buf(c->pool, 2); if (c->buffer == NULL) { goto abort; } c->buffer->start[0] = CR; c->buffer->start[1] = LF; #endif /* create the fake request */ r = ngx_pcalloc(c->pool, sizeof(ngx_http_request_t)); if (r == NULL) { goto abort; } c->requests++; logctx->request = r; logctx->current_request = r; r->pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, c->log); if (r->pool == NULL) { goto abort; } dd("r pool allocated: %d", (int) (sizeof(ngx_http_lua_ctx_t) + sizeof(void *) * ngx_http_max_module + sizeof(ngx_http_cleanup_t))); #if 0 hc = ngx_pcalloc(c->pool, sizeof(ngx_http_connection_t)); if (hc == NULL) { goto abort; } r->header_in = c->buffer; r->header_end = c->buffer->start; if (ngx_list_init(&r->headers_out.headers, r->pool, 0, sizeof(ngx_table_elt_t)) != NGX_OK) { goto abort; } if (ngx_list_init(&r->headers_in.headers, r->pool, 0, sizeof(ngx_table_elt_t)) != NGX_OK) { goto abort; } #endif r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module); if (r->ctx == NULL) { goto abort; } #if 0 cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module); r->variables = ngx_pcalloc(r->pool, cmcf->variables.nelts * sizeof(ngx_http_variable_value_t)); if (r->variables == NULL) { goto abort; } #endif r->connection = c; r->main_conf = tctx.main_conf; r->srv_conf = tctx.srv_conf; r->loc_conf = tctx.loc_conf; dd("lmcf: %p", lmcf); ctx = ngx_http_lua_create_ctx(r); if (ctx == NULL) { goto abort; } if (tctx.vm_state) { ctx->vm_state = tctx.vm_state; pcln = ngx_pool_cleanup_add(r->pool, 0); if (pcln == NULL) { goto abort; } pcln->handler = ngx_http_lua_cleanup_vm; pcln->data = tctx.vm_state; } r->headers_in.content_length_n = 0; c->data = r; #if 0 hc->request = r; r->http_connection = hc; #endif r->signature = NGX_HTTP_MODULE; r->main = r; r->count = 1; r->method = NGX_HTTP_UNKNOWN; r->headers_in.keep_alive_n = -1; r->uri_changes = NGX_HTTP_MAX_URI_CHANGES + 1; r->subrequests = NGX_HTTP_MAX_SUBREQUESTS + 1; r->http_state = NGX_HTTP_PROCESS_REQUEST_STATE; r->discard_body = 1; clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); c->log->file = clcf->error_log->file; if (!(c->log->log_level & NGX_LOG_DEBUG_CONNECTION)) { c->log->log_level = clcf->error_log->log_level; } c->error = 1; ctx->cur_co_ctx = &ctx->entry_co_ctx; L = ngx_http_lua_get_lua_vm(r, ctx); cln = ngx_http_cleanup_add(r, 0); if (cln == NULL) { goto abort; } cln->handler = ngx_http_lua_request_cleanup_handler; cln->data = ctx; ctx->cleanup = &cln->handler; ctx->entered_content_phase = 1; ctx->context = NGX_HTTP_LUA_CONTEXT_TIMER; r->read_event_handler = ngx_http_block_reading; ctx->cur_co_ctx->co_ref = tctx.co_ref; ctx->cur_co_ctx->co = tctx.co; ctx->cur_co_ctx->co_status = NGX_HTTP_LUA_CO_RUNNING; dd("r connection: %p, log %p", r->connection, r->connection->log); /* save the request in coroutine globals table */ ngx_http_lua_set_req(tctx.co, r); lmcf->running_timers++; lua_pushboolean(tctx.co, tctx.premature); n = lua_gettop(tctx.co); if (n > 2) { lua_insert(tctx.co, 2); } rc = ngx_http_lua_run_thread(L, r, ctx, n - 1); dd("timer lua run thread: %d", (int) rc); if (rc == NGX_ERROR || rc >= NGX_OK) { /* do nothing */ } else if (rc == NGX_AGAIN) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 0); } else if (rc == NGX_DONE) { rc = ngx_http_lua_content_run_posted_threads(L, r, ctx, 1); } else { rc = NGX_OK; } ngx_http_lua_finalize_request(r, rc); return; abort: if (tctx.co_ref && tctx.co) { lua_pushlightuserdata(tctx.co, &ngx_http_lua_coroutines_key); lua_rawget(tctx.co, LUA_REGISTRYINDEX); luaL_unref(tctx.co, -1, tctx.co_ref); lua_settop(tctx.co, 0); } if (tctx.vm_state) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, "decrementing " "the reference count for Lua VM: %i", tctx.vm_state->count); tctx.vm_state->count--; } if (r && r->pool) { ngx_destroy_pool(r->pool); } if (c) { ngx_http_lua_close_fake_connection(c); } }
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; }
int lcurl_util_pcall_method(lua_State *L, const char *name, int nargs, int nresults, int errfunc){ int obj_index = -nargs - 1; lua_getfield(L, obj_index, name); lua_insert(L, obj_index - 1); return lua_pcall(L, nargs + 1, nresults, errfunc); }
static void maybe_insert_default_mv(lua_State *L) { if ((lua_gettop(L) >= 1 && lua_type(L, 1) != LUA_TSTRING) || lua_gettop(L) == 0) { lua_pushstring(L, am_conf_default_modelview_matrix_name); lua_insert(L, 1); } }
void ListDirectoryContents(lua_State *L, const char *currentDir) { std::wstring wsConvert; xl::text::transcode::UTF8_to_Unicode(currentDir, strlen(currentDir), wsConvert); const wchar_t *wCurrentDir =wsConvert.c_str(); if (wcscmp(wCurrentDir, L"") == 0) { wchar_t szLogicalDriveStrings[MAX_PATH]; //获取驱动器的内存 wchar_t *szDrive; ::ZeroMemory(szLogicalDriveStrings, MAX_PATH); //将内存清零,第一个参数是申请字符的地址 ::GetLogicalDriveStrings(MAX_PATH-1, szLogicalDriveStrings); //获取磁盘中的所有驱动器 szDrive=(wchar_t*)szLogicalDriveStrings; lua_newtable(L); int index = 1; do { int len = wcslen(szDrive); std::string sDriveConvert; xl::text::transcode::Unicode_to_UTF8(szDrive, wcslen(szDrive), sDriveConvert); const char* volume = sDriveConvert.c_str(); UINT uDriveType = GetDriveType(szDrive); lua_newtable(L); lua_pushnumber(L, 1); lua_pushboolean(L, true); // has children lua_settable(L, -3); lua_pushnumber(L, 2); lua_pushstring(L, volume); lua_settable(L, -3); lua_pushnumber(L, index); lua_insert(L, -2); // 把栈顶的一维索引和rowtable换一下位置, lua_settable(L, -3); // 把刚压栈的一维索引row, 和rowtable弹出, 放在要返回的return table中 index++; szDrive += (len+1); } while(*szDrive!='\x00'); } else { WIN32_FIND_DATA fdFile; HANDLE hFind = NULL; wchar_t wPath[MAX_PATH]; wsprintf(wPath, L"%s\\*", wCurrentDir); if( (hFind = FindFirstFile(wPath, &fdFile)) == INVALID_HANDLE_VALUE) { return; } int index = 1; lua_newtable(L); do { if (wcscmp(fdFile.cFileName, L".") != 0 && wcscmp(fdFile.cFileName, L"..") != 0 && !(fdFile.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) && !(fdFile.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)) { lua_newtable(L); lua_pushnumber(L, 1); if (fdFile.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { lua_pushboolean(L, true); } else { lua_pushboolean(L, false); } lua_settable(L, -3); std::string subDirString; xl::text::transcode::Unicode_to_UTF8(fdFile.cFileName, MAX_PATH, subDirString); lua_pushnumber(L, 2); lua_pushstring(L, subDirString.c_str()); lua_settable(L, -3); lua_pushnumber(L, index);//把一维索引row压栈 lua_insert(L, -2); // 把栈顶的一维索引和rowtable换一下位置, lua_settable(L, -3); // 把刚压栈的一维索引row, 和rowtable弹出, 放在要返回的return table中 index++; } } while(::FindNextFile(hFind, &fdFile)); ::FindClose(hFind); } return; }
ngx_int_t ngx_http_lua_header_filter_by_chunk(lua_State *L, ngx_http_request_t *r) { int old_exit_code = 0; ngx_int_t rc; u_char *err_msg; size_t len; #if (NGX_PCRE) ngx_pool_t *old_pool; #endif ngx_http_lua_ctx_t *ctx; ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx->exited) { old_exit_code = ctx->exit_code; } /* initialize nginx context in Lua VM, code chunk at stack top sp = 1 */ ngx_http_lua_header_filter_by_lua_env(L, r); #if (NGX_PCRE) /* XXX: work-around to nginx regex subsystem */ old_pool = ngx_http_lua_pcre_malloc_init(r->pool); #endif lua_pushcfunction(L, ngx_http_lua_traceback); lua_insert(L, 1); /* put it under chunk and args */ /* protected call user code */ rc = lua_pcall(L, 0, 1, 1); lua_remove(L, 1); /* remove traceback function */ #if (NGX_PCRE) /* XXX: work-around to nginx regex subsystem */ ngx_http_lua_pcre_malloc_done(old_pool); #endif dd("rc == %d", (int) rc); if (rc != 0) { /* error occurred when running loaded code */ err_msg = (u_char *) lua_tolstring(L, -1, &len); if (err_msg == NULL) { err_msg = (u_char *) "unknown reason"; len = sizeof("unknown reason") - 1; } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to run header_filter_by_lua*: %*s", len, err_msg); lua_settop(L, 0); /* clear remaining elems on stack */ return NGX_ERROR; } dd("exited: %d, exit code: %d, old exit code: %d", (int) ctx->exited, (int) ctx->exit_code, (int) old_exit_code); #if 1 /* clear Lua stack */ lua_settop(L, 0); #endif if (ctx->exited && ctx->exit_code != old_exit_code) { if (ctx->exit_code == NGX_ERROR) { return NGX_ERROR; } dd("finalize request with %d", (int) ctx->exit_code); rc = ngx_http_filter_finalize_request(r, &ngx_http_lua_module, ctx->exit_code); if (rc == NGX_ERROR || rc == NGX_AGAIN) { return rc; } return NGX_DECLINED; } return NGX_OK; }
int CorsixTH_lua_main_no_eval(lua_State *L) { // assert(_VERSION == LUA_VERSION) size_t iLength; lua_getglobal(L, "_VERSION"); const char* sVersion = lua_tolstring(L, -1, &iLength); if(iLength != strlen(LUA_VERSION) || strcmp(sVersion, LUA_VERSION) != 0) { lua_pushliteral(L, "Linked against a version of Lua different to the " "one used when compiling.\nPlease recompile CorsixTH against the " "same Lua version it is linked against."); sendCommand(jvm,COMMAND_GAME_LOAD_ERROR); return lua_error(L); } lua_pop(L, 1); // registry._CLEANUP = {} lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "_CLEANUP"); // math.random* = Mersenne twister variant luaT_cpcall(L, luaopen_random, NULL); // package.preload["jit.opt"] = load(jit_opt_lua) // package.preload["jit.opt_inline"] = load(jit_opt_inline_lua) lua_getglobal(L, "package"); lua_getfield(L, -1, "preload"); luaL_loadbuffer(L, (const char*)jit_opt_lua, sizeof(jit_opt_lua), "jit/opt.luac"); lua_setfield(L, -2, "jit.opt"); luaL_loadbuffer(L, (const char*)jit_opt_inline_lua, sizeof(jit_opt_inline_lua), "jit/opt_inline.luac"); lua_setfield(L, -2, "jit.opt_inline"); lua_pop(L, 2); // if registry._LOADED.jit then // require"jit.opt".start() // else // print "Notice: ..." // end // (this could be done in Lua rather than here, but ideally the optimiser // should be turned on before any Lua code is loaded) lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); lua_getfield(L, -1, "jit"); if(lua_type(L, -1) == LUA_TNIL) { lua_pop(L, 2); lua_getglobal(L, "print"); lua_pushliteral(L, "Notice: LuaJIT not being used.\nConsider replacing" " Lua with LuaJIT to improve performance."); #ifdef CORSIX_TH_64BIT lua_pushliteral(L, " Note that there is not currently a 64 bit version" " of LuaJIT."); lua_concat(L, 2); #endif lua_call(L, 1, 0); } else { lua_pop(L, 2); lua_getglobal(L, "require"); lua_pushliteral(L, "jit.opt"); lua_call(L, 1, 1); lua_getfield(L, -1, "start"); lua_call(L, 0, 0); lua_pop(L, 1); } // Fill in package.preload table so that calls to require("X") from Lua // will call the appropriate luaopen_X function in C. #define PRELOAD(name, fn) \ luaT_execute(L, "package.preload." name " = ...", fn) PRELOAD("lfs", luaopen_lfs_ext); PRELOAD("lpeg", luaopen_lpeg); PRELOAD("rnc", luaopen_rnc); PRELOAD("TH", luaopen_th); PRELOAD("ISO_FS", luaopen_iso_fs); PRELOAD("persist", luaopen_persist); PRELOAD("sdl", luaopen_sdl); #undef PRELOAD // require "debug" (Harmless in Lua 5.1, useful in 5.2 for compatbility) luaT_execute(L, "require \"debug\""); // Check for --interpreter and run that instead of CorsixTH.lua bool bGotScriptFile = false; int iNArgs = lua_gettop(L); for(int i = 1; i <= iNArgs; ++i) { if(lua_type(L, i) == LUA_TSTRING) { size_t iLen; const char* sCmd = lua_tolstring(L, i, &iLen); if(iLen > 14 && memcmp(sCmd, "--interpreter=", 14) == 0) { lua_getglobal(L, "assert"); lua_getglobal(L, "loadfile"); lua_pushlstring(L, sCmd + 14, iLen - 14); bGotScriptFile = true; break; } } } JNIEnv* jEnv; jvm->AttachCurrentThread(&jEnv, NULL); jclass cls = jEnv->FindClass("uk/co/armedpineapple/cth/SDLActivity"); jmethodID method = jEnv->GetStaticMethodID(cls, "nativeGetGamePath", "()Ljava/lang/String;"); jstring jpath = (jstring) jEnv->CallStaticObjectMethod(cls, method); const char* path = jEnv->GetStringUTFChars(jpath, 0); // Code to try several variations on finding CorsixTH.lua: // CorsixTH.lua // CorsixTH/CorsixTH.lua // ../CorsixTH.lua // ../CorsixTH/CorsixTH.lua // ../../CorsixTH.lua // ../../CorsixTH/CorsixTH.lua // ../../../CorsixTH.lua // ../../../CorsixTH/CorsixTH.lua // It is simpler to write this in Lua than in C. std::string sLuaCorsixTHLua( "local name, sep, code = \"CorsixTH.lua\", package.config:sub(1, 1)\n" "local root = (... or \"\"):match(\"^(.*[\"..sep..\"])\") or \"\"\n" "code = loadfile(\""); sLuaCorsixTHLua.append(path); sLuaCorsixTHLua.append("\"..name)\n" "if code then return code end\n" #ifdef __APPLE__ // Darrell: Search inside the bundle first. // There's probably a better way of doing this. #if defined(IS_CORSIXTH_APP) "code = loadfile(\"CorsixTH.app/Contents/Resources/\"..name)\n" "if code then return code end\n" #elif defined(IS_MAPEDIT_APP) "code = loadfile(\"MapEdit.app/Contents/Resources/\"..name)\n" "if code then return code end\n" #endif #endif "for num_dotdot = 0, 3 do\n" " for num_dir = 0, 1 do\n" " code = loadfile(root..(\"..\"..sep):rep(num_dotdot)..\n" " (\"CorsixTH\"..sep):rep(num_dir)..name)\n" " if code then return code end \n" " end \n" "end \n" "return loadfile(name)"); jEnv->ReleaseStringUTFChars(jpath, path); // return assert(loadfile"CorsixTH.lua")(...) if(!bGotScriptFile) { lua_getglobal(L, "assert"); luaL_loadbuffer(L, sLuaCorsixTHLua.c_str(), sLuaCorsixTHLua.length(), "@main.cpp (l_main bootstrap)"); if(lua_gettop(L) == 2) lua_pushnil(L); else lua_pushvalue(L, 1); } lua_call(L, 1, 2); lua_call(L, 2, 1); lua_insert(L, 1); return lua_gettop(L); }
static int vlclua_add_callback( lua_State *L ) { vlclua_callback_t *p_callback; static int i_index = 0; vlc_object_t **pp_obj = luaL_checkudata( L, 1, "vlc_object" ); const char *psz_var = luaL_checkstring( L, 2 ); lua_settop( L, 4 ); /* makes sure that optional data arg is set */ if( !lua_isfunction( L, 3 ) ) return vlclua_error( L ); i_index++; p_callback = (vlclua_callback_t*)malloc( sizeof( vlclua_callback_t ) ); if( !p_callback ) return vlclua_error( L ); /* obj var func data */ lua_getglobal( L, "vlc" ); /* obj var func data vlc */ lua_getfield( L, -1, "callbacks" ); if( lua_isnil( L, -1 ) ) { lua_pop( L, 1 ); lua_newtable( L ); lua_setfield( L, -2, "callbacks" ); lua_getfield( L, -1, "callbacks" ); } /* obj var func data vlc callbacks */ lua_remove( L, -2 ); /* obj var func data callbacks */ lua_pushinteger( L, i_index ); /* obj var func data callbacks index */ lua_insert( L, -4 ); /* obj var index func data callbacks */ lua_insert( L, -4 ); /* obj var callbacks index func data */ lua_createtable( L, 0, 0 ); /* obj var callbacks index func data cbtable */ lua_insert( L, -2 ); /* obj var callbacks index func cbtable data */ lua_setfield( L, -2, "data" ); /* obj var callbacks index func cbtable */ lua_insert( L, -2 ); /* obj var callbacks index cbtable func */ lua_setfield( L, -2, "callback" ); /* obj var callbacks index cbtable */ lua_pushlightuserdata( L, *pp_obj ); /* will be needed in vlclua_del_callback */ /* obj var callbacks index cbtable p_obj */ lua_setfield( L, -2, "private1" ); /* obj var callbacks index cbtable */ lua_pushvalue( L, 2 ); /* will be needed in vlclua_del_callback */ /* obj var callbacks index cbtable var */ lua_setfield( L, -2, "private2" ); /* obj var callbacks index cbtable */ lua_pushlightuserdata( L, p_callback ); /* will be needed in vlclua_del_callback */ /* obj var callbacks index cbtable p_callback */ lua_setfield( L, -2, "private3" ); /* obj var callbacks index cbtable */ lua_settable( L, -3 ); /* obj var callbacks */ lua_pop( L, 3 ); /* <empty stack> */ /* Do not move this before the lua specific code (it somehow changes * the function in the stack to nil) */ p_callback->i_index = i_index; p_callback->i_type = var_Type( *pp_obj, psz_var ); p_callback->L = lua_newthread( L ); /* Do we have to keep a reference to this thread somewhere to prevent garbage collection? */ var_AddCallback( *pp_obj, psz_var, vlclua_callback, p_callback ); return 0; }
static int js_getter_index (lua_State* L) { // stack: self, key, _self while (lua_gettop(L) < 3) { lua_pushnil(L); } // _self or self if (lua_isnil(L, 3)) { lua_pushvalue(L, 1); } else { lua_pushvalue(L, 3); } if (lua_getmetatable(L, -1) == 0) { lua_pushnil(L); return 1; } // stack: self, key, _self, (_self or self), mt // Check getters lua_getfield(L, -1, "getters"); if (!lua_isnil(L, -1)) { lua_pushvalue(L, 2); lua_rawget(L, -2); if (!lua_isnil(L, -1)) { lua_pushvalue(L, 1); lua_call(L, 1, 1); return 1; } lua_remove(L, -1); } lua_remove(L, -1); // stack: self, key, _self, (_self or self), mt // Get raw key or defer to proto getter lua_pushvalue(L, 2); // stack: self, key, _self, (_self or self), mt, key lua_rawget(L, -3); // stack: self, key, _self, (_self or self), mt, (_self or self)[key] if (lua_isnil(L, -1)) { // stack: self, key, _self, (_self or self), mt, nil lua_getfield(L, -2, "proto"); // stack: self, key, _self, (_self or self), mt, nil, mt.proto lua_insert(L, 2); // stack: self, mt.proto, key, _self, (_self or self), mt, nil lua_remove(L, -1); // stack: self, mt.proto, key, _self, (_self or self), mt lua_remove(L, -1); // stack: self, mt.proto, key, _self, (_self or self) lua_remove(L, -1); // stack: self, mt.proto, key, _self lua_remove(L, -1); // stack: self, mt.proto, key return js_proto_get(L); } return 1; }
// Push the list of callbacks (a lua table). // Then push nargs arguments. // Then call this function, which // - runs the callbacks // - removes the table and arguments from the lua stack // - pushes the return value, computed depending on mode void scriptapi_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode) { // Insert the return value into the lua stack, below the table assert(lua_gettop(L) >= nargs + 1); lua_pushnil(L); lua_insert(L, -(nargs + 1) - 1); // Stack now looks like this: // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n> int rv = lua_gettop(L) - nargs - 1; int table = rv + 1; int arg = table + 1; luaL_checktype(L, table, LUA_TTABLE); // Foreach lua_pushnil(L); bool first_loop = true; while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 luaL_checktype(L, -1, LUA_TFUNCTION); // Call function for(int i = 0; i < nargs; i++) lua_pushvalue(L, arg+i); if(lua_pcall(L, nargs, 1, 0)) script_error(L, "error: %s", lua_tostring(L, -1)); // Move return value to designated space in stack // Or pop it if(first_loop){ // Result of first callback is always moved lua_replace(L, rv); first_loop = false; } else { // Otherwise, what happens depends on the mode if(mode == RUN_CALLBACKS_MODE_FIRST) lua_pop(L, 1); else if(mode == RUN_CALLBACKS_MODE_LAST) lua_replace(L, rv); else if(mode == RUN_CALLBACKS_MODE_AND || mode == RUN_CALLBACKS_MODE_AND_SC){ if((bool)lua_toboolean(L, rv) == true && (bool)lua_toboolean(L, -1) == false) lua_replace(L, rv); else lua_pop(L, 1); } else if(mode == RUN_CALLBACKS_MODE_OR || mode == RUN_CALLBACKS_MODE_OR_SC){ if((bool)lua_toboolean(L, rv) == false && (bool)lua_toboolean(L, -1) == true) lua_replace(L, rv); else lua_pop(L, 1); } else assert(0); } // Handle short circuit modes if(mode == RUN_CALLBACKS_MODE_AND_SC && (bool)lua_toboolean(L, rv) == false) break; else if(mode == RUN_CALLBACKS_MODE_OR_SC && (bool)lua_toboolean(L, rv) == true) break; // value removed, keep key for next iteration } // Remove stuff from stack, leaving only the return value lua_settop(L, rv); // Fix return value in case no callbacks were called if(first_loop){ if(mode == RUN_CALLBACKS_MODE_AND || mode == RUN_CALLBACKS_MODE_AND_SC){ lua_pop(L, 1); lua_pushboolean(L, true); } else if(mode == RUN_CALLBACKS_MODE_OR || mode == RUN_CALLBACKS_MODE_OR_SC){ lua_pop(L, 1); lua_pushboolean(L, false); } } }
/* * Push a proxy userdata on the stack. * returns NULL if ok, else some error string related to bad idfunc behavior or module require problem * (error cannot happen with mode_ == eLM_ToKeeper) * * Initializes necessary structures if it's the first time 'idfunc' is being * used in this Lua state (metatable, registring it). Otherwise, increments the * reference count. */ char const* push_deep_proxy( struct s_Universe* U, lua_State* L, DEEP_PRELUDE* prelude, enum eLookupMode mode_) { DEEP_PRELUDE** proxy; // Check if a proxy already exists push_registry_subtable_mode( L, DEEP_PROXY_CACHE_KEY, "v"); // DPC lua_pushlightuserdata( L, prelude->deep); // DPC deep lua_rawget( L, -2); // DPC proxy if ( !lua_isnil( L, -1)) { lua_remove( L, -2); // proxy return NULL; } else { lua_pop( L, 1); // DPC } MUTEX_LOCK( &U->deep_lock); ++ (prelude->refcount); // one more proxy pointing to this deep data MUTEX_UNLOCK( &U->deep_lock); STACK_GROW( L, 7); STACK_CHECK( L); proxy = lua_newuserdata( L, sizeof( DEEP_PRELUDE*)); // DPC proxy ASSERT_L( proxy); *proxy = prelude; // Get/create metatable for 'idfunc' (in this state) lua_pushlightuserdata( L, prelude->idfunc); // DPC proxy idfunc get_deep_lookup( L); // DPC proxy metatable? if( lua_isnil( L, -1)) // // No metatable yet. { char const* modname; int oldtop = lua_gettop( L); // DPC proxy nil lua_pop( L, 1); // DPC proxy // 1 - make one and register it if( mode_ != eLM_ToKeeper) { prelude->idfunc( L, eDO_metatable); // DPC proxy metatable deepversion if( lua_gettop( L) - oldtop != 1 || !lua_istable( L, -2) || !lua_isstring( L, -1)) { lua_settop( L, oldtop); // DPC proxy X lua_pop( L, 3); // return "Bad idfunc(eOP_metatable): unexpected pushed value"; } luaG_pushdeepversion( L); // DPC proxy metatable deepversion deepversion if( !lua501_equal( L, -1, -2)) { lua_pop( L, 5); // return "Bad idfunc(eOP_metatable): mismatched deep version"; } lua_pop( L, 2); // DPC proxy metatable // make sure the idfunc didn't export __gc, as we will store our own lua_getfield( L, -1, "__gc"); // DPC proxy metatable __gc if( !lua_isnil( L, -1)) { lua_pop( L, 4); // return "idfunc-created metatable shouldn't contain __gc"; } lua_pop( L, 1); // DPC proxy metatable } else { // keepers need a minimal metatable that only contains __gc lua_newtable( L); // DPC proxy metatable } // Add our own '__gc' method lua_pushcfunction( L, deep_userdata_gc); // DPC proxy metatable __gc lua_setfield( L, -2, "__gc"); // DPC proxy metatable // Memorize for later rounds lua_pushvalue( L, -1); // DPC proxy metatable metatable lua_pushlightuserdata( L, prelude->idfunc); // DPC proxy metatable metatable idfunc set_deep_lookup( L); // DPC proxy metatable // 2 - cause the target state to require the module that exported the idfunc // this is needed because we must make sure the shared library is still loaded as long as we hold a pointer on the idfunc { int oldtop = lua_gettop( L); modname = (char const*) prelude->idfunc( L, eDO_module); // DPC proxy metatable // make sure the function pushed nothing on the stack! if( lua_gettop( L) - oldtop != 0) { lua_pop( L, 3); // return "Bad idfunc(eOP_module): should not push anything"; } } if( modname) // we actually got a module name { // somehow, L.registry._LOADED can exist without having registered the 'package' library. lua_getglobal( L, "require"); // DPC proxy metatable require() // check that the module is already loaded (or being loaded, we are happy either way) if( lua_isfunction( L, -1)) { lua_pushstring( L, modname); // DPC proxy metatable require() "module" lua_getfield( L, LUA_REGISTRYINDEX, "_LOADED"); // DPC proxy metatable require() "module" _R._LOADED if( lua_istable( L, -1)) { bool_t alreadyloaded; lua_pushvalue( L, -2); // DPC proxy metatable require() "module" _R._LOADED "module" lua_rawget( L, -2); // DPC proxy metatable require() "module" _R._LOADED module alreadyloaded = lua_toboolean( L, -1); if( !alreadyloaded) // not loaded { int require_result; lua_pop( L, 2); // DPC proxy metatable require() "module" // require "modname" require_result = lua_pcall( L, 1, 0, 0); // DPC proxy metatable error? if( require_result != LUA_OK) { // failed, return the error message lua_pushfstring( L, "error while requiring '%s' identified by idfunc(eOP_module): ", modname); lua_insert( L, -2); // DPC proxy metatable prefix error lua_concat( L, 2); // DPC proxy metatable error return lua_tostring( L, -1); } } else // already loaded, we are happy { lua_pop( L, 4); // DPC proxy metatable } } else // no L.registry._LOADED; can this ever happen? { lua_pop( L, 6); // return "unexpected error while requiring a module identified by idfunc(eOP_module)"; } } else // a module name, but no require() function :-( { lua_pop( L, 4); // return "lanes receiving deep userdata should register the 'package' library"; } } } STACK_MID( L, 2); // DPC proxy metatable ASSERT_L( lua_isuserdata( L, -2)); ASSERT_L( lua_istable( L, -1)); lua_setmetatable( L, -2); // DPC proxy // If we're here, we obviously had to create a new proxy, so cache it. lua_pushlightuserdata( L, (*proxy)->deep); // DPC proxy deep lua_pushvalue( L, -2); // DPC proxy deep proxy lua_rawset( L, -4); // DPC proxy lua_remove( L, -2); // proxy ASSERT_L( lua_isuserdata( L, -1)); STACK_END( L, 0); return NULL; }
//////////////////////////////////////////////// // parse object from struct address and offset // function parseMemberObj(className, structAddress, offset) // push a object with type className to stack // int luaU_parseMemberObj(lua_State* L) { typedef LMREG::voidPtr2user voidPtr2user; const char* className = luaL_checkstring(L, 1); void* structAddr = NULL; if(lua_isnumber(L,2)) { structAddr = (void*)(uint_r)luaL_checknumber(L, 2); } else if(lua_islightuserdata(L,2)) { structAddr = lua_touserdata(L,2); } else if(lua_isstring(L, 2)) { structAddr = (void*)lua_tostring(L, 2); } else if(lua_isstring(L,2)) { structAddr = (void*)lua_tostring(L, 2); } else { luaL_argerror(L, 2, "address must be a number or pointer"); return 0; } if(!lua_isnumber(L, 3)) { luaL_argerror(L, 3, "offset must be a number value (1 based)"); return 0; } int offset = (int)lua_tonumber(L, 3); if(offset < 1) { luaL_argerror(L, 3, "offset must be a number value (1 based)"); return 0; } void* addr = *(void**)((char*)structAddr + offset - 1); if (!addr) { lua_pushnil(L); return 1; } lua_pushstring(L, className); lua_gettable(L, LUA_GLOBALSINDEX); if(!lua_istable(L, -1)) { luaL_argerror(L, 1, "metatable for classname not found"); return 0; } lua_pushstring(L, "__ref"); lua_gettable(L, -2); if(lua_istable(L, -1)) { lua_remove(L, -2); lua_pushlightuserdata(L, addr); //lua_pushnumber(L, (DWORD)addr); lua_rawget(L, -2); ASSERT(lua_isuserdata(L, -1)); lua_remove(L, -2); } else { lua_pop(L, 1); void* pUserData = lua_newuserdata(L, sizeof(voidPtr2user)); new (pUserData) voidPtr2user(addr); lua_insert(L, -2); lua_setmetatable(L, -2); } return 1; }
static int py_asfunc_call(lua_State *L) { lua_pushvalue(L, lua_upvalueindex(1)); lua_insert(L, 1); return py_object_call(L); }
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; }
/** ** Change the diplomacy from ThisPlayer to another player. ** ** @param l Lua state. */ static int CclDiplomacy(lua_State *l) { lua_pushnumber(l, ThisPlayer->Index); lua_insert(l, 1); return CclSetDiplomacy(l); }
/* note: this expects that the lua stack already contains the mapping rule, * needed by sbox_translate_path (lua code). * at exit the rule is still there. */ char *call_lua_function_sbox_translate_path( const path_mapping_context_t *ctx, int result_log_level, const char *abs_clean_virtual_path, int *flagsp, char **exec_policy_name_ptr) { struct sb2context *sb2ctx = ctx->pmc_sb2ctx; int flags; char *host_path = NULL; SB_LOG(SB_LOGLEVEL_NOISE, "calling sbox_translate_path for %s(%s), fn_class=0x%X", ctx->pmc_func_name, abs_clean_virtual_path, ctx->pmc_fn_class); if (!sb2ctx->lua) sb2context_initialize_lua(sb2ctx); SB_LOG(SB_LOGLEVEL_NOISE, "call_lua_function_sbox_translate_path: gettop=%d", lua_gettop(sb2ctx->lua)); if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) { dump_lua_stack("call_lua_function_sbox_translate_path entry", sb2ctx->lua); } lua_getfield(sb2ctx->lua, LUA_GLOBALSINDEX, "sbox_translate_path"); /* stack now contains the rule object and string "sbox_translate_path", * move the string to the bottom: */ lua_insert(sb2ctx->lua, -2); /* add other parameters */ lua_pushstring(sb2ctx->lua, ctx->pmc_binary_name); lua_pushstring(sb2ctx->lua, ctx->pmc_func_name); lua_pushstring(sb2ctx->lua, abs_clean_virtual_path); lua_pushnumber(sb2ctx->lua, ctx->pmc_fn_class); /* 5 arguments, returns rule,policy,path,flags */ lua_call(sb2ctx->lua, 5, 4); host_path = (char *)lua_tostring(sb2ctx->lua, -2); if (host_path && (*host_path != '/')) { SB_LOG(SB_LOGLEVEL_ERROR, "Mapping failed: Result is not absolute ('%s'->'%s')", abs_clean_virtual_path, host_path); host_path = NULL; } else if (host_path) { host_path = strdup(host_path); } flags = lua_tointeger(sb2ctx->lua, -1); check_mapping_flags(flags, "sbox_translate_path"); if (flagsp) *flagsp = flags; if (exec_policy_name_ptr) { char *exec_policy_name; if (*exec_policy_name_ptr) { free(*exec_policy_name_ptr); *exec_policy_name_ptr = NULL; } exec_policy_name = (char *)lua_tostring(sb2ctx->lua, -3); if (exec_policy_name) { *exec_policy_name_ptr = strdup(exec_policy_name); } } lua_pop(sb2ctx->lua, 3); /* leave the rule to the stack */ if (host_path) { char *new_host_path = clean_and_log_fs_mapping_result(ctx, abs_clean_virtual_path, result_log_level, host_path, flags); free(host_path); host_path = new_host_path; } if (!host_path) { SB_LOG(SB_LOGLEVEL_ERROR, "No result from sbox_translate_path for: %s '%s'", ctx->pmc_func_name, abs_clean_virtual_path); } SB_LOG(SB_LOGLEVEL_NOISE, "call_lua_function_sbox_translate_path: at exit, gettop=%d", lua_gettop(sb2ctx->lua)); if(SB_LOG_IS_ACTIVE(SB_LOGLEVEL_NOISE3)) { dump_lua_stack("call_lua_function_sbox_translate_path exit", sb2ctx->lua); } return(host_path); }
/** ** Change the shared vision from ThisPlayer to another player. ** ** @param l Lua state. */ static int CclSharedVision(lua_State *l) { lua_pushnumber(l, ThisPlayer->Index); lua_insert(l, 1); return CclSetSharedVision(l); }
/** * wifi.sta.listap() * Description: * scan and get ap list as a lua table into callback function. * Syntax: * wifi.sta.getap(function(table)) * wifi.sta.getap(format, function(table)) * wifi.sta.getap(cfg, function(table)) * wifi.sta.getap(cfg, format, function(table)) * Parameters: * cfg: table that contains scan configuration * Format:Select output table format. * 0 for the old format (SSID : Authmode, RSSI, BSSID, Channel) (Default) * 1 for the new format (BSSID : SSID, RSSI, Authmode, Channel) * function(table): a callback function to receive ap table when scan is done this function receive a table, the key is the ssid, value is other info in format: authmode,rssi,bssid,channel * Returns: * nil * * Example: --original function left intact to preserve backward compatibility wifi.sta.getap(function(T) for k,v in pairs(T) do print(k..":"..v) end end) --if no scan configuration is desired cfg can be set to nil or previous example can be used wifi.sta.getap(nil, function(T) for k,v in pairs(T) do print(k..":"..v) end end) --scan configuration scan_cfg={} scan_cfg.ssid="myssid" --if set to nil, ssid is not filtered scan_cfg.bssid="AA:AA:AA:AA:AA:AA" --if set to nil, MAC address is not filtered scan_cfg.channel=0 --if set to nil, channel will default to 0(scans all channels), if set scan will be faster scan_cfg.show_hidden=1 --if set to nil, show_hidden will default to 0 wifi.sta.getap(scan_cfg, function(T) for k,v in pairs(T) do print(k..":"..v) end end) */ static int wifi_station_listap( lua_State* L ) { if(wifi_get_opmode() == SOFTAP_MODE) { return luaL_error( L, "Can't list ap in SOFTAP mode" ); } gL = L; struct scan_config scan_cfg; getap_output_format=0; if (lua_type(L, 1)==LUA_TTABLE) { char ssid[32]; char bssid[6]; uint8 channel=0; uint8 show_hidden=0; size_t len; lua_getfield(L, 1, "ssid"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *ssidstr = luaL_checklstring( L, -1, &len ); if(len>32) return luaL_error( L, "ssid:<32" ); c_memset(ssid, 0, 32); c_memcpy(ssid, ssidstr, len); scan_cfg.ssid=ssid; NODE_DBG(scan_cfg.ssid); NODE_DBG("\n"); } else return luaL_error( L, "wrong arg type" ); } else scan_cfg.ssid=NULL; lua_getfield(L, 1, "bssid"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isstring(L, -1) ) // deal with the ssid string { const char *macaddr = luaL_checklstring( L, -1, &len ); if(len!=17) return luaL_error( L, "bssid: FF:FF:FF:FF:FF:FF" ); c_memset(bssid, 0, 6); os_str2macaddr(bssid, macaddr); scan_cfg.bssid=bssid; NODE_DBG(MACSTR, MAC2STR(scan_cfg.bssid)); NODE_DBG("\n"); } else return luaL_error( L, "wrong arg type" ); } else scan_cfg.bssid=NULL; lua_getfield(L, 1, "channel"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isnumber(L, -1) ) // deal with the ssid string { channel = luaL_checknumber( L, -1); if(!(channel>=0 && channel<=13)) return luaL_error( L, "channel: 0 or 1-13" ); scan_cfg.channel=channel; NODE_DBG("%d\n", scan_cfg.channel); } else return luaL_error( L, "wrong arg type" ); } else scan_cfg.channel=0; lua_getfield(L, 1, "show_hidden"); if (!lua_isnil(L, -1)){ /* found? */ if( lua_isnumber(L, -1) ) // deal with the ssid string { show_hidden = luaL_checknumber( L, -1); if(show_hidden!=0 && show_hidden!=1) return luaL_error( L, "show_hidden: 0 or 1" ); scan_cfg.show_hidden=show_hidden; NODE_DBG("%d\n", scan_cfg.show_hidden); } else return luaL_error( L, "wrong arg type" ); } else scan_cfg.show_hidden=0; if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) { lua_pushnil(L); lua_insert(L, 2); } lua_pop(L, -4); } else if (lua_type(L, 1) == LUA_TNUMBER) { lua_pushnil(L); lua_insert(L, 1); } else if (lua_type(L, 1) == LUA_TFUNCTION || lua_type(L, 1) == LUA_TLIGHTFUNCTION) { lua_pushnil(L); lua_insert(L, 1); lua_pushnil(L); lua_insert(L, 1); } else if(lua_isnil(L, 1)) { if (lua_type(L, 2) == LUA_TFUNCTION || lua_type(L, 2) == LUA_TLIGHTFUNCTION) { lua_pushnil(L); lua_insert(L, 2); } } else { return luaL_error( L, "wrong arg type" ); } if (lua_type(L, 2) == LUA_TNUMBER) //this section changes the output format { getap_output_format=luaL_checkinteger( L, 2 ); if ( getap_output_format != 0 && getap_output_format != 1) return luaL_error( L, "wrong arg type" ); } NODE_DBG("Use alternate output format: %d\n", getap_output_format); if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION) { lua_pushvalue(L, 3); // copy argument (func) to the top of stack if(wifi_scan_succeed != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed); wifi_scan_succeed = luaL_ref(L, LUA_REGISTRYINDEX); if (lua_type(L, 1)==LUA_TTABLE) { wifi_station_scan(&scan_cfg,wifi_scan_done); } else { wifi_station_scan(NULL,wifi_scan_done); } } else { if(wifi_scan_succeed != LUA_NOREF) luaL_unref(L, LUA_REGISTRYINDEX, wifi_scan_succeed); wifi_scan_succeed = LUA_NOREF; } }
const char *LuaSerializer::unpickle(lua_State *l, const char *pos) { LUA_DEBUG_START(l); char type = *pos++; switch (type) { case 'f': { char *end; double f = strtod(pos, &end); if (pos == end) throw SavedGameCorruptException(); lua_pushnumber(l, f); pos = end+1; // skip newline break; } case 'b': { if (*pos != '0' && *pos != '1') throw SavedGameCorruptException(); bool b = (*pos == '0') ? false : true; lua_pushboolean(l, b); pos++; break; } case 's': { char *end; int len = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); end++; // skip newline lua_pushlstring(l, end, len); pos = end + len; break; } case 't': { lua_newtable(l); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); pos = unpickle(l, pos); lua_pushvalue(l, -3); lua_rawset(l, -3); lua_pop(l, 1); while (*pos != 'n') { pos = unpickle(l, pos); pos = unpickle(l, pos); lua_rawset(l, -3); } pos++; break; } case 'r': { pos = unpickle(l, pos); lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); lua_pushvalue(l, -2); lua_rawget(l, -2); if (lua_isnil(l, -1)) throw SavedGameCorruptException(); lua_insert(l, -3); lua_pop(l, 2); break; } case 'u': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline if (len == 10 && strncmp(pos, "SystemPath", 10) == 0) { pos = end; Sint32 sectorX = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorY = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Sint32 sectorZ = strtol(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Uint32 systemNum = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Uint32 sbodyId = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline SystemPath *sbp = new SystemPath(sectorX, sectorY, sectorZ, systemNum, sbodyId); LuaSystemPath::PushToLuaGC(sbp); break; } if (len == 4 && strncmp(pos, "Body", 4) == 0) { pos = end; Uint32 n = strtoul(pos, const_cast<char**>(&end), 0); if (pos == end) throw SavedGameCorruptException(); pos = end+1; // skip newline Body *body = Pi::game->GetSpace()->GetBodyByIndex(n); if (pos == end) throw SavedGameCorruptException(); switch (body->GetType()) { case Object::BODY: LuaBody::PushToLua(body); break; case Object::SHIP: LuaShip::PushToLua(dynamic_cast<Ship*>(body)); break; case Object::SPACESTATION: LuaSpaceStation::PushToLua(dynamic_cast<SpaceStation*>(body)); break; case Object::PLANET: LuaPlanet::PushToLua(dynamic_cast<Planet*>(body)); break; case Object::STAR: LuaStar::PushToLua(dynamic_cast<Star*>(body)); break; case Object::PLAYER: LuaPlayer::PushToLua(dynamic_cast<Player*>(body)); break; default: throw SavedGameCorruptException(); } break; } throw SavedGameCorruptException(); } case 'o': { const char *end = strchr(pos, '\n'); if (!end) throw SavedGameCorruptException(); int len = end - pos; end++; // skip newline const char *cl = pos; // unpickle the object, and insert it beneath the method table value pos = unpickle(l, end); // get _G[typename] lua_rawgeti(l, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); lua_pushlstring(l, cl, len); lua_gettable(l, -2); lua_remove(l, -2); if (lua_isnil(l, -1)) { lua_pop(l, 2); break; } lua_getfield(l, -1, "Unserialize"); if (lua_isnil(l, -1)) { lua_pushlstring(l, cl, len); luaL_error(l, "No Unserialize method found for class '%s'\n", lua_tostring(l, -1)); } lua_insert(l, -3); lua_pop(l, 1); pi_lua_protected_call(l, 1, 1); break; } default: throw SavedGameCorruptException(); } LUA_DEBUG_END(l, 1); return pos; }
static void nlua_thread(int pin, int pout, char *project, char *filename) { char cmd[4096]; int cmd_size; fprintf(stderr, "[err] Starting up Lua interpreter...\n"); fprintf(stdout, "[out] Starting up Lua interpreter...\n"); lua_State *L; L = lua_open(); if (!L) { cmd[0] = LC_ERROR; cmd_size = snprintf(cmd+1, sizeof(cmd)-2, "Unable to open lua") + 1; write(1, cmd, cmd_size); exit(0); } luaL_openlibs(L); lua_sethook(L, nlua_interpret_hook, LUA_MASKLINE, 0); /* If a filename was specified, load it in and run it */ if (project && *project) { char full_filename[2048]; if (filename && *filename) snprintf(full_filename, sizeof(full_filename)-1, "%s/%s/%s", PROJECT_DIR, project, filename); else snprintf(full_filename, sizeof(full_filename)-1, "%s/%s", PROJECT_DIR, project); if (luaL_dofile(L, full_filename)) { cmd[0] = LC_ERROR; cmd_size = snprintf(cmd+1, sizeof(cmd)-2, "Error: %s", lua_tostring(L, 1)) + 1; write(1, cmd, cmd_size); } } /* If no file was specified, enter REPL mode */ else { printf("Entering REPL mode...\n"); int status; while ((status = loadline(L)) != -1) { if (status == 0) status = docall(L, 0, 0); report(L, status); if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ lua_getglobal(L, "print"); lua_insert(L, 1); if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) l_message(progname, lua_pushfstring(L, "error calling " LUA_QL("print") " (%s)", lua_tostring(L, -1))); } } lua_settop(L, 0); fputs("\n", stdout); fflush(stdout); } lua_close(L); close(pin); close(pout); exit(0); return; }
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL) { static char buf[256]; LUA_DEBUG_START(l); idx = lua_absindex(l, idx); if (lua_getmetatable(l, idx)) { lua_getfield(l, -1, "class"); if (lua_isnil(l, -1)) lua_pop(l, 2); else { const char *cl = lua_tostring(l, -1); snprintf(buf, sizeof(buf), "o%s\n", cl); lua_getglobal(l, cl); if (lua_isnil(l, -1)) luaL_error(l, "No Serialize method found for class '%s'\n", cl); lua_getfield(l, -1, "Serialize"); if (lua_isnil(l, -1)) luaL_error(l, "No Serialize method found for class '%s'\n", cl); lua_pushvalue(l, idx); pi_lua_protected_call(l, 1, 1); lua_remove(l, idx); lua_insert(l, idx); lua_pop(l, 3); if (lua_isnil(l, idx)) { LUA_DEBUG_END(l, 0); return; } out += buf; } } switch (lua_type(l, idx)) { case LUA_TNIL: break; case LUA_TNUMBER: { snprintf(buf, sizeof(buf), "f%f\n", lua_tonumber(l, idx)); out += buf; break; } case LUA_TBOOLEAN: { snprintf(buf, sizeof(buf), "b%d", lua_toboolean(l, idx) ? 1 : 0); out += buf; break; } case LUA_TSTRING: { lua_pushvalue(l, idx); const char *str = lua_tostring(l, -1); snprintf(buf, sizeof(buf), "s" SIZET_FMT "\n", strlen(str)); out += buf; out += str; lua_pop(l, 1); break; } case LUA_TTABLE: { lua_pushinteger(l, lua_Integer(lua_topointer(l, idx))); // ptr lua_getfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs"); // ptr reftable lua_pushvalue(l, -2); // ptr reftable ptr lua_rawget(l, -2); // ptr reftable ??? if (!lua_isnil(l, -1)) { out += "r"; pickle(l, -3, out, key); lua_pop(l, 3); // [empty] } else { out += "t"; lua_pushvalue(l, -3); // ptr reftable nil ptr lua_pushvalue(l, idx); // ptr reftable nil ptr table lua_rawset(l, -4); // ptr reftable nil pickle(l, -3, out, key); lua_pop(l, 3); // [empty] lua_pushvalue(l, idx); lua_pushnil(l); while (lua_next(l, -2)) { if (key) { pickle(l, -2, out, key); pickle(l, -1, out, key); } else { lua_pushvalue(l, -2); const char *k = lua_tostring(l, -1); pickle(l, -3, out, k); pickle(l, -2, out, k); lua_pop(l, 1); } lua_pop(l, 1); } lua_pop(l, 1); out += "n"; } break; } case LUA_TUSERDATA: { out += "u"; lid *idp = static_cast<lid*>(lua_touserdata(l, idx)); LuaObjectBase *lo = LuaObjectBase::Lookup(*idp); if (!lo) Error("Lua serializer '%s' tried to serialize object with id 0x%08x, but it no longer exists", key, *idp); // XXX object wrappers should really have Serialize/Unserialize // methods to deal with this if (lo->Isa("SystemPath")) { SystemPath *sbp = dynamic_cast<SystemPath*>(lo->m_object); snprintf(buf, sizeof(buf), "SystemPath\n%d\n%d\n%d\n%u\n%u\n", sbp->sectorX, sbp->sectorY, sbp->sectorZ, sbp->systemIndex, sbp->bodyIndex); out += buf; break; } if (lo->Isa("Body")) { Body *b = dynamic_cast<Body*>(lo->m_object); snprintf(buf, sizeof(buf), "Body\n%u\n", Pi::game->GetSpace()->GetIndexForBody(b)); out += buf; break; } Error("Lua serializer '%s' tried to serialize unsupported userdata value", key); break; } default: Error("Lua serializer '%s' tried to serialize %s value", key, lua_typename(l, lua_type(l, idx))); break; } LUA_DEBUG_END(l, 0); }
ngx_int_t ngx_http_lua_body_filter_by_chunk(lua_State *L, ngx_http_request_t *r, ngx_chain_t *in) { ngx_int_t rc; u_char *err_msg; size_t len; #if (NGX_PCRE) ngx_pool_t *old_pool; #endif dd("initialize nginx context in Lua VM, code chunk at stack top sp = 1"); ngx_http_lua_body_filter_by_lua_env(L, r, in); #if (NGX_PCRE) /* XXX: work-around to nginx regex subsystem */ old_pool = ngx_http_lua_pcre_malloc_init(r->pool); #endif lua_pushcfunction(L, ngx_http_lua_traceback); lua_insert(L, 1); /* put it under chunk and args */ dd("protected call user code"); rc = lua_pcall(L, 0, 1, 1); lua_remove(L, 1); /* remove traceback function */ #if (NGX_PCRE) /* XXX: work-around to nginx regex subsystem */ ngx_http_lua_pcre_malloc_done(old_pool); #endif if (rc != 0) { /* error occured */ err_msg = (u_char *) lua_tolstring(L, -1, &len); if (err_msg == NULL) { err_msg = (u_char *) "unknown reason"; len = sizeof("unknown reason") - 1; } ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "failed to run body_filter_by_lua*: %*s", len, err_msg); lua_settop(L, 0); /* clear remaining elems on stack */ return NGX_ERROR; } /* rc == 0 */ rc = (ngx_int_t) lua_tointeger(L, -1); dd("got return value: %d", (int) rc); lua_settop(L, 0); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return NGX_ERROR; } return NGX_OK; }
// in: linda_ud [, key [, ...]] int keepercall_count( lua_State* L) { int top; push_table( L, 1); // ud keys fifos switch( lua_gettop( L)) { // no key is specified: return a table giving the count of all known keys case 2: // ud fifos lua_newtable( L); // ud fifos out lua_replace( L, 1); // out fifos lua_pushnil( L); // out fifos nil while( lua_next( L, 2)) // out fifos key fifo { keeper_fifo* fifo = prepare_fifo_access( L, -1); // out fifos key fifo lua_pop( L, 1); // out fifos key lua_pushvalue( L, -1); // out fifos key key lua_pushinteger( L, fifo->count); // out fifos key key count lua_rawset( L, -5); // out fifos key } lua_pop( L, 1); // out break; // 1 key is specified: return its count case 3: // ud key fifos { keeper_fifo* fifo; lua_replace( L, 1); // fifos key lua_rawget( L, -2); // fifos fifo fifo = prepare_fifo_access( L, -1); // fifos fifo lua_pushinteger( L, fifo->count); // fifos fifo count lua_replace( L, -3); // count fifo lua_pop( L, 1); // count } break; // a variable number of keys is specified: return a table of their counts default: // ud keys fifos lua_newtable( L); // ud keys fifos out lua_replace( L, 1); // out keys fifos // shifts all keys up in the stack. potentially slow if there are a lot of them, but then it should be bearable lua_insert( L, 2); // out fifos keys while( (top = lua_gettop( L)) > 2) { keeper_fifo* fifo; lua_pushvalue( L, -1); // out fifos keys key lua_rawget( L, 2); // out fifos keys fifo fifo = prepare_fifo_access( L, -1); // out fifos keys fifo lua_pop( L, 1); // out fifos keys if( fifo) { lua_pushinteger( L, fifo->count); // out fifos keys count lua_rawset( L, 1); // out fifos keys } else { lua_pop( L, 1); // out fifos keys } } lua_pop( L, 1); // out } return 1; }
/*! * \brief Store the sort order of each context * In the event of an error, an error string will be pushed onto the lua stack. * * \retval 0 success * \retval 1 failure */ static int lua_sort_extensions(lua_State *L) { int extensions, extensions_order; /* create the extensions_order table */ lua_newtable(L); lua_setfield(L, LUA_REGISTRYINDEX, "extensions_order"); lua_getfield(L, LUA_REGISTRYINDEX, "extensions_order"); extensions_order = lua_gettop(L); /* sort each context in the extensions table */ /* load the 'extensions' table */ lua_getglobal(L, "extensions"); extensions = lua_gettop(L); if (lua_isnil(L, -1)) { lua_pop(L, 1); lua_pushstring(L, "Unable to find 'extensions' table in extensions.lua\n"); return 1; } /* iterate through the extensions table and create a * matching table (holding the sort order) in the * extensions_order table for each context that is found */ for (lua_pushnil(L); lua_next(L, extensions); lua_pop(L, 1)) { int context = lua_gettop(L); int context_name = context - 1; int context_order; /* copy the context_name to be used as the key for the * context_order table in the extensions_order table later */ lua_pushvalue(L, context_name); /* create the context_order table */ lua_newtable(L); context_order = lua_gettop(L); /* iterate through this context an popluate the corrisponding * table in the extensions_order table */ for (lua_pushnil(L); lua_next(L, context); lua_pop(L, 1)) { int exten = lua_gettop(L) - 1; lua_pushinteger(L, lua_objlen(L, context_order) + 1); lua_pushvalue(L, exten); lua_settable(L, context_order); } lua_settable(L, extensions_order); /* put the context_order table in the extensions_order table */ /* now sort the new table */ /* push the table.sort function */ lua_getglobal(L, "table"); lua_getfield(L, -1, "sort"); lua_remove(L, -2); /* remove the 'table' table */ /* push the context_order table */ lua_pushvalue(L, context_name); lua_gettable(L, extensions_order); /* push the comp function */ lua_pushcfunction(L, &lua_extension_cmp); if (lua_pcall(L, 2, 0, 0)) { lua_insert(L, -5); lua_pop(L, 4); return 1; } } /* remove the extensions table and the extensions_order table */ lua_pop(L, 2); return 0; }
/* | The effective main for one run. | | HUP signals may cause several runs of the one main. */ int main1( int argc, char *argv[] ) { // the Lua interpreter lua_State * L; // the runner file char * lsyncd_runner_file = NULL; int argp = 1; // load Lua L = luaL_newstate( ); luaL_openlibs( L ); { // checks the lua version const char * version; int major, minor; lua_getglobal( L, "_VERSION" ); version = luaL_checkstring( L, -1 ); if( sscanf( version, "Lua %d.%d", &major, &minor ) != 2 ) { fprintf( stderr, "cannot parse lua library version!\n" ); exit (-1 ); } if( major < 5 || (major == 5 && minor < 1) ) { fprintf( stderr, "Lua library is too old. Needs 5.1 at least" ); exit( -1 ); } lua_pop( L, 1 ); } { // logging is prepared quite early int i = 1; add_logcat( "Normal", LOG_NOTICE ); add_logcat( "Warn", LOG_WARNING ); add_logcat( "Error", LOG_ERR ); while( i < argc ) { if( strcmp( argv[ i ], "-log" ) && strcmp( argv[ i ], "--log" ) ) { // arg is neither -log or --log i++; continue; } if( ++i >= argc ) { // -(-)log was last argument break; } if( !add_logcat( argv[ i ], LOG_NOTICE ) ) { printlogf( L, "Error", "'%s' is not a valid logging category", argv[ i ] ); exit( -1 ); } } } // registers Lsycnd's core library register_lsyncd( L ); if( check_logcat( "Debug" ) <= settings.log_level ) { // printlogf doesnt support %ld :-( printf( "kernels clocks_per_sec=%ld\n", clocks_per_sec ); } // checks if the user overrode the default runner file if( argp < argc && !strcmp( argv[ argp ], "--runner" ) ) { if (argp + 1 >= argc) { logstring( "Error", "Lsyncd Lua-runner file missing after --runner " ); exit( -1 ); } lsyncd_runner_file = argv[ argp + 1 ]; argp += 2; } if( lsyncd_runner_file ) { // checks if the runner file exists struct stat st; if( stat( lsyncd_runner_file, &st ) ) { printlogf( L, "Error", "Cannot see a runner at '%s'.", lsyncd_runner_file ); exit( -1 ); } // loads the runner file if( luaL_loadfile(L, lsyncd_runner_file ) ) { printlogf( L, "Error", "error loading '%s': %s", lsyncd_runner_file, lua_tostring( L, -1 ) ); exit( -1 ); } } else { // loads the runner from binary if( luaL_loadbuffer( L, runner_out, runner_size, "runner" ) ) { printlogf( L, "Error", "error loading precompiled runner: %s", lua_tostring( L, -1 ) ); exit( -1 ); } } // prepares the runner executing the script { if( lua_pcall( L, 0, LUA_MULTRET, 0 ) ) { printlogf( L, "Error", "preparing runner: %s", lua_tostring( L, -1 ) ); exit( -1 ); } lua_pushlightuserdata( L, (void *) & runner ); // switches the value ( result of preparing ) and the key &runner lua_insert( L, 1 ); // saves the table of the runners functions in the lua registry lua_settable( L, LUA_REGISTRYINDEX ); // saves the error function extras // &callError is the key lua_pushlightuserdata ( L, (void *) &callError ); // &runner[ callError ] the value lua_pushlightuserdata ( L, (void *) &runner ); lua_gettable ( L, LUA_REGISTRYINDEX ); lua_pushstring ( L, "callError" ); lua_gettable ( L, -2 ); lua_remove ( L, -2 ); lua_settable ( L, LUA_REGISTRYINDEX ); } // asserts the Lsyncd's version matches // between runner and core { const char *lversion; lua_getglobal( L, "lsyncd_version" ); lversion = luaL_checkstring( L, -1 ); if( strcmp( lversion, PACKAGE_VERSION ) ) { printlogf( L, "Error", "Version mismatch '%s' is '%s', but core is '%s'", lsyncd_runner_file ? lsyncd_runner_file : "( internal runner )", lversion, PACKAGE_VERSION ); exit( -1 ); } lua_pop( L, 1 ); } // loads the defaults from binary { if( luaL_loadbuffer( L, defaults_out, defaults_size, "defaults" ) ) { printlogf( L, "Error", "loading defaults: %s", lua_tostring( L, -1 ) ); exit( -1 ); } // prepares the defaults if( lua_pcall( L, 0, 0, 0 ) ) { printlogf( L, "Error", "preparing defaults: %s", lua_tostring( L, -1 ) ); exit( -1 ); } } // checks if there is a "-help" or "--help" { int i; for( i = argp; i < argc; i++ ) { if ( !strcmp( argv[ i ], "-help" ) || !strcmp( argv[ i ], "--help" ) ) { load_runner_func( L, "help" ); if( lua_pcall( L, 0, 0, -2 ) ) { exit( -1 ); } lua_pop( L, 1 ); exit( 0 ); } } } // starts the option parser in Lua script { int idx = 1; const char *s; // creates a table with all remaining argv option arguments load_runner_func( L, "configure" ); lua_newtable( L ); while( argp < argc ) { lua_pushnumber ( L, idx++ ); lua_pushstring ( L, argv[ argp++ ] ); lua_settable ( L, -3 ); } // creates a table with the cores event monitor interfaces idx = 0; lua_newtable( L ); while( monitors[ idx ] ) { lua_pushnumber ( L, idx + 1 ); lua_pushstring ( L, monitors[ idx++ ] ); lua_settable ( L, -3 ); } if( lua_pcall( L, 2, 1, -4 ) ) { exit( -1 ); } if( first_time ) { // If not first time, simply retains the config file given s = lua_tostring(L, -1); if( s ) { lsyncd_config_file = s_strdup( s ); } } lua_pop( L, 2 ); } // checks existence of the config file if( lsyncd_config_file ) { struct stat st; // gets the absolute path to the config file // so in case of HUPing the daemon, it finds it again char * apath = get_realpath( lsyncd_config_file ); if( !apath ) { printlogf( L, "Error", "Cannot find config file at '%s'.", lsyncd_config_file ); exit( -1 ); } free( lsyncd_config_file ); lsyncd_config_file = apath; if( stat( lsyncd_config_file, &st ) ) { printlogf( L, "Error", "Cannot find config file at '%s'.", lsyncd_config_file ); exit( -1 ); } // loads and executes the config file if( luaL_loadfile( L, lsyncd_config_file ) ) { printlogf( L, "Error", "error loading %s: %s", lsyncd_config_file, lua_tostring( L, -1 ) ); exit( -1 ); } if( lua_pcall( L, 0, LUA_MULTRET, 0) ) { printlogf( L, "Error", "error preparing %s: %s", lsyncd_config_file, lua_tostring( L, -1 ) ); exit( -1 ); } } #ifdef WITH_INOTIFY open_inotify( L ); #endif #ifdef WITH_FSEVENTS open_fsevents( L ); #endif // adds signal handlers // listens to SIGCHLD, but blocks it until pselect( ) // opens the signal handler up { sigset_t set; sigemptyset( &set ); sigaddset( &set, SIGCHLD ); signal( SIGCHLD, sig_child ); sigprocmask( SIG_BLOCK, &set, NULL ); signal( SIGHUP, sig_handler ); signal( SIGTERM, sig_handler ); signal( SIGINT, sig_handler ); } // runs initializations from runner // it will set the configuration and add watches { load_runner_func( L, "initialize" ); lua_pushboolean( L, first_time ); if( lua_pcall( L, 1, 0, -3 ) ) { exit( -1 ); } lua_pop( L, 1 ); } // // enters the master loop // masterloop( L ); // // cleanup // // tidies up all observances { int i; for( i = 0; i < observances_len; i++ ) { struct observance *obs = observances + i; obs->tidy( obs ); } observances_len = 0; nonobservances_len = 0; } // frees logging categories { int ci; struct logcat *lc; for( ci = 'A'; ci <= 'Z'; ci++ ) { for( lc = logcats[ ci - 'A' ]; lc && lc->name; lc++) { free( lc->name ); lc->name = NULL; } if( logcats[ci - 'A' ] ) { free( logcats[ ci - 'A' ] ); logcats[ ci - 'A' ] = NULL; } } } lua_close( L ); return 0; }