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 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 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 (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; } /* clear Lua stack */ lua_settop(L, 0); return NGX_OK; }
int w_World_getContactFilter(lua_State *L) { World *t = luax_checkworld(L, 1); lua_remove(L, 1); return t->getContactFilter(L); }
void _pklua_lua_socket_free_buffer(lua_State* L, int stack_pos) { lua_remove(L, stack_pos); }
void LuaSerializer::pickle(lua_State *l, int idx, std::string &out, const char *key = NULL) { static char buf[256]; LUA_DEBUG_START(l); idx = (idx < 0) ? lua_gettop(l)+idx+1 : 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_getfield(l, LUA_GLOBALSINDEX, 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%d\n%d\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%d\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); }
int w_World_queryBoundingBox(lua_State *L) { World *t = luax_checkworld(L, 1); lua_remove(L, 1); return t->queryBoundingBox(L); }
/* * error, data, read_len = port:read(max_read_len [[, timeout_ms], forced]) * * if forced > 0 then read() blocks until 'timeout_ms' or there's 'max_read_len' * bytes available */ static int lua_port_read(lua_State *L) { int ret = 0; int argc = 0; int forced = 0; unsigned int timeout = 0; unsigned int len = 0; unsigned int bytes_read = 0; unsigned char *data = NULL; struct rs232_port_t *p = NULL; p = (struct rs232_port_t*) luaL_checkudata(L, 1, MODULE_NAMESPACE); lua_remove(L, 1); if (p == NULL || !rs232_port_open(p)) { lua_pushinteger(L, RS232_ERR_PORT_CLOSED); lua_pushnil(L); lua_pushinteger(L, 0); return 3; } argc = lua_gettop(L); switch (argc) { case 1: len = (unsigned int) luaL_checkinteger(L, 1); data = (unsigned char*) malloc(len * sizeof(unsigned char *)); memset(data, 0, len); ret = rs232_read(p, data, len, &bytes_read); break; case 2: case 3: len = (unsigned int) luaL_checknumber(L, 1); data = (unsigned char*) malloc(len * sizeof(unsigned char *)); memset(data, 0, len); timeout = (unsigned int) luaL_checknumber(L, 2); forced = luaL_optint(L, 3, 0); if (forced > 0) ret = rs232_read_timeout_forced(p, data, len, &bytes_read, timeout); else ret = rs232_read_timeout(p, data, len, &bytes_read, timeout); break; default: lua_pushinteger(L, RS232_ERR_UNKNOWN); lua_pushnil(L); lua_pushinteger(L, 0); return 3; } DBG("ret=%d hex='%s' bytes_read=%d\n", ret, rs232_hex_dump(data, bytes_read), bytes_read); lua_pushinteger(L, RS232_ERR_NOERROR); if (bytes_read > 0) lua_pushlstring(L, (char *) data, bytes_read); else lua_pushnil(L); if (data) free(data); lua_pushinteger(L, bytes_read); return 3; }
static int ngx_http_lua_ngx_location_capture_multi(lua_State *L) { ngx_http_request_t *r; ngx_http_request_t *sr = NULL; /* subrequest object */ ngx_http_post_subrequest_t *psr; ngx_http_lua_ctx_t *sr_ctx; ngx_http_lua_ctx_t *ctx; ngx_array_t *extra_vars; ngx_str_t uri; ngx_str_t args; ngx_str_t extra_args; ngx_uint_t flags; u_char *p; u_char *q; size_t len; size_t nargs; int rc; int n; int always_forward_body = 0; ngx_uint_t method; ngx_http_request_body_t *body; int type; ngx_buf_t *b; unsigned vars_action; ngx_uint_t nsubreqs; ngx_uint_t index; size_t sr_statuses_len; size_t sr_headers_len; size_t sr_bodies_len; size_t sr_flags_len; size_t ofs1, ofs2; unsigned custom_ctx; ngx_http_lua_co_ctx_t *coctx; ngx_http_lua_post_subrequest_data_t *psr_data; n = lua_gettop(L); if (n != 1) { return luaL_error(L, "only one argument is expected, but got %d", n); } luaL_checktype(L, 1, LUA_TTABLE); nsubreqs = lua_objlen(L, 1); if (nsubreqs == 0) { return luaL_error(L, "at least one subrequest should be specified"); } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request object found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); coctx = ctx->cur_co_ctx; if (coctx == NULL) { return luaL_error(L, "no co ctx found"); } ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua location capture, uri:\"%V\" c:%ud", &r->uri, r->main->count); sr_statuses_len = nsubreqs * sizeof(ngx_int_t); sr_headers_len = nsubreqs * sizeof(ngx_http_headers_out_t *); sr_bodies_len = nsubreqs * sizeof(ngx_str_t); sr_flags_len = nsubreqs * sizeof(uint8_t); p = ngx_pcalloc(r->pool, sr_statuses_len + sr_headers_len + sr_bodies_len + sr_flags_len); if (p == NULL) { return luaL_error(L, "no memory"); } coctx->sr_statuses = (void *) p; p += sr_statuses_len; coctx->sr_headers = (void *) p; p += sr_headers_len; coctx->sr_bodies = (void *) p; p += sr_bodies_len; coctx->sr_flags = (void *) p; coctx->nsubreqs = nsubreqs; coctx->pending_subreqs = 0; extra_vars = NULL; for (index = 0; index < nsubreqs; index++) { coctx->pending_subreqs++; lua_rawgeti(L, 1, index + 1); if (lua_isnil(L, -1)) { return luaL_error(L, "only array-like tables are allowed"); } dd("queries query: top %d", lua_gettop(L)); if (lua_type(L, -1) != LUA_TTABLE) { return luaL_error(L, "the query argument %d is not a table, " "but a %s", index, lua_typename(L, lua_type(L, -1))); } nargs = lua_objlen(L, -1); if (nargs != 1 && nargs != 2) { return luaL_error(L, "query argument %d expecting one or " "two arguments", index); } lua_rawgeti(L, 2, 1); /* queries query uri */ dd("queries query uri: %d", lua_gettop(L)); dd("first arg in first query: %s", lua_typename(L, lua_type(L, -1))); body = NULL; ngx_str_null(&extra_args); if (extra_vars != NULL) { /* flush out existing elements in the array */ extra_vars->nelts = 0; } vars_action = 0; custom_ctx = 0; if (nargs == 2) { /* check out the options table */ lua_rawgeti(L, 2, 2); /* queries query uri opts */ dd("queries query uri opts: %d", lua_gettop(L)); if (lua_type(L, 4) != LUA_TTABLE) { return luaL_error(L, "expecting table as the 2nd argument for " "subrequest %d, but got %s", index, luaL_typename(L, 4)); } dd("queries query uri opts: %d", lua_gettop(L)); /* check the args option */ lua_getfield(L, 4, "args"); type = lua_type(L, -1); switch (type) { case LUA_TTABLE: ngx_http_lua_process_args_option(r, L, -1, &extra_args); break; case LUA_TNIL: /* do nothing */ break; case LUA_TNUMBER: case LUA_TSTRING: extra_args.data = (u_char *) lua_tolstring(L, -1, &len); extra_args.len = len; break; default: return luaL_error(L, "Bad args option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the vars option */ lua_getfield(L, 4, "vars"); switch (lua_type(L, -1)) { case LUA_TTABLE: ngx_http_lua_process_vars_option(r, L, -1, &extra_vars); dd("post process vars top: %d", lua_gettop(L)); break; case LUA_TNIL: /* do nothing */ break; default: return luaL_error(L, "Bad vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the share_all_vars option */ lua_getfield(L, 4, "share_all_vars"); switch (lua_type(L, -1)) { case LUA_TNIL: /* do nothing */ break; case LUA_TBOOLEAN: if (lua_toboolean(L, -1)) { vars_action |= NGX_HTTP_LUA_SHARE_ALL_VARS; } break; default: return luaL_error(L, "Bad share_all_vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the copy_all_vars option */ lua_getfield(L, 4, "copy_all_vars"); switch (lua_type(L, -1)) { case LUA_TNIL: /* do nothing */ break; case LUA_TBOOLEAN: if (lua_toboolean(L, -1)) { vars_action |= NGX_HTTP_LUA_COPY_ALL_VARS; } break; default: return luaL_error(L, "Bad copy_all_vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the "forward_body" option */ lua_getfield(L, 4, "always_forward_body"); always_forward_body = lua_toboolean(L, -1); lua_pop(L, 1); dd("always foward body: %d", always_forward_body); /* check the "method" option */ lua_getfield(L, 4, "method"); type = lua_type(L, -1); if (type == LUA_TNIL) { method = NGX_HTTP_GET; } else { if (type != LUA_TNUMBER) { return luaL_error(L, "Bad http request method"); } method = (ngx_uint_t) lua_tonumber(L, -1); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the "ctx" option */ lua_getfield(L, 4, "ctx"); type = lua_type(L, -1); if (type != LUA_TNIL) { if (type != LUA_TTABLE) { return luaL_error(L, "Bad ctx option value type %s, " "expected a Lua table", lua_typename(L, type)); } custom_ctx = 1; } else { lua_pop(L, 1); } dd("queries query uri opts ctx?: %d", lua_gettop(L)); /* check the "body" option */ lua_getfield(L, 4, "body"); type = lua_type(L, -1); if (type != LUA_TNIL) { if (type != LUA_TSTRING && type != LUA_TNUMBER) { return luaL_error(L, "Bad http request body"); } body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (body == NULL) { return luaL_error(L, "no memory"); } q = (u_char *) lua_tolstring(L, -1, &len); dd("request body: [%.*s]", (int) len, q); if (len) { b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return luaL_error(L, "no memory"); } b->last = ngx_copy(b->last, q, len); body->bufs = ngx_alloc_chain_link(r->pool); if (body->bufs == NULL) { return luaL_error(L, "no memory"); } body->bufs->buf = b; body->bufs->next = NULL; body->buf = b; } } lua_pop(L, 1); /* pop the body */ /* stack: queries query uri opts ctx? */ lua_remove(L, 4); /* stack: queries query uri ctx? */ dd("queries query uri ctx?: %d", lua_gettop(L)); } else { method = NGX_HTTP_GET; } /* stack: queries query uri ctx? */ p = (u_char *) luaL_checklstring(L, 3, &len); uri.data = ngx_palloc(r->pool, len); if (uri.data == NULL) { return luaL_error(L, "memory allocation error"); } ngx_memcpy(uri.data, p, len); uri.len = len; ngx_str_null(&args); flags = 0; rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags); if (rc != NGX_OK) { dd("rc = %d", (int) rc); return luaL_error(L, "unsafe uri in argument #1: %s", p); } if (args.len == 0) { if (extra_args.len) { p = ngx_palloc(r->pool, extra_args.len); if (p == NULL) { return luaL_error(L, "no memory"); } ngx_memcpy(p, extra_args.data, extra_args.len); args.data = p; args.len = extra_args.len; } } else if (extra_args.len) { /* concatenate the two parts of args together */ len = args.len + (sizeof("&") - 1) + extra_args.len; p = ngx_palloc(r->pool, len); if (p == NULL) { return luaL_error(L, "no memory"); } q = ngx_copy(p, args.data, args.len); *q++ = '&'; ngx_memcpy(q, extra_args.data, extra_args.len); args.data = p; args.len = len; } ofs1 = ngx_align(sizeof(ngx_http_post_subrequest_t), sizeof(void *)); ofs2 = ngx_align(sizeof(ngx_http_lua_ctx_t), sizeof(void *)); p = ngx_palloc(r->pool, ofs1 + ofs2 + sizeof(ngx_http_lua_post_subrequest_data_t)); if (p == NULL) { return luaL_error(L, "no memory"); } psr = (ngx_http_post_subrequest_t *) p; p += ofs1; sr_ctx = (ngx_http_lua_ctx_t *) p; ngx_http_lua_assert((void *) sr_ctx == ngx_align_ptr(sr_ctx, sizeof(void *))); p += ofs2; psr_data = (ngx_http_lua_post_subrequest_data_t *) p; ngx_http_lua_assert((void *) psr_data == ngx_align_ptr(psr_data, sizeof(void *))); ngx_memzero(sr_ctx, sizeof(ngx_http_lua_ctx_t)); /* set by ngx_memzero: * sr_ctx->run_post_subrequest = 0 * sr_ctx->free = NULL * sr_ctx->body = NULL */ psr_data->ctx = sr_ctx; psr_data->pr_co_ctx = coctx; psr->handler = ngx_http_lua_post_subrequest; psr->data = psr_data; rc = ngx_http_lua_subrequest(r, &uri, &args, &sr, psr, 0); if (rc != NGX_OK) { return luaL_error(L, "failed to issue subrequest: %d", (int) rc); } ngx_http_lua_init_ctx(sr, sr_ctx); sr_ctx->capture = 1; sr_ctx->index = index; sr_ctx->last_body = &sr_ctx->body; sr_ctx->vm_state = ctx->vm_state; ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module); rc = ngx_http_lua_adjust_subrequest(sr, method, always_forward_body, body, vars_action, extra_vars); if (rc != NGX_OK) { ngx_http_lua_cancel_subreq(sr); return luaL_error(L, "failed to adjust the subrequest: %d", (int) rc); } dd("queries query uri opts ctx? %d", lua_gettop(L)); /* stack: queries query uri ctx? */ if (custom_ctx) { ngx_http_lua_ngx_set_ctx_helper(L, sr, sr_ctx, -1); lua_pop(L, 3); } else { lua_pop(L, 2); } /* stack: queries */ } if (extra_vars) { ngx_array_destroy(extra_vars); } ctx->no_abort = 1; return lua_yield(L, 0); }
void lua_removef(lua_State *L, int index) { lua_remove(L, index); }
int Xml_eval(lua_State *L) { char* str = 0; size_t str_size=0; if(lua_isuserdata(L,1)) str = (char*)lua_touserdata(L,1); else { const char * sTmp = luaL_checklstring(L,1,&str_size); str = (char*)malloc(str_size+1); memcpy(str, sTmp, str_size); str[str_size]=0; } Tokenizer* tok = Tokenizer_new(str, str_size ? str_size : strlen(str)); lua_settop(L,0); const char* token=0; int firstStatement = 1; while((token=Tokenizer_next(tok))!=0) if(token[0]==OPN) { // new tag found if(lua_gettop(L)) { int newIndex=lua_rawlen(L,-1)+1; lua_pushnumber(L,newIndex); lua_newtable(L); lua_settable(L, -3); lua_pushnumber(L,newIndex); lua_gettable(L,-2); } else { if (firstStatement) { lua_newtable(L); firstStatement = 0; } else return lua_gettop(L); } // set metatable: lua_newtable(L); lua_pushliteral(L, "__index"); lua_getglobal(L, "xml"); lua_settable(L, -3); lua_pushliteral(L, "__tostring"); // set __tostring metamethod lua_getglobal(L, "xml"); lua_pushliteral(L,"str"); lua_gettable(L, -2); lua_remove(L, -2); lua_settable(L, -3); lua_setmetatable(L, -2); // parse tag and content: lua_pushnumber(L,0); // use index 0 for storing the tag lua_pushstring(L, Tokenizer_next(tok)); lua_settable(L, -3); while(((token = Tokenizer_next(tok))!=0)&&(token[0]!=CLS)&&(token[0]!=ESC)) { // parse tag header size_t sepPos=find(token, "=", 0); if(token[sepPos]) { // regular attribute const char* aVal =token+sepPos+2; lua_pushlstring(L, token, sepPos); size_t lenVal = strlen(aVal)-1; if(!lenVal) Xml_pushDecode(L, "", 0); else Xml_pushDecode(L, aVal, lenVal); lua_settable(L, -3); } } if(!token||(token[0]==ESC)) { if(lua_gettop(L)>1) lua_settop(L,-2); // this tag has no content, only attributes else break; } } else if(token[0]==ESC) { // previous tag is over if(lua_gettop(L)>1) lua_settop(L,-2); // pop current table else break; } else { // read elements lua_pushnumber(L,lua_rawlen(L,-1)+1); Xml_pushDecode(L, token, 0); lua_settable(L, -3); } Tokenizer_delete(tok); free(str); return lua_gettop(L); }
static void mar_decode_value (lua_State *L, const char *buf, size_t len, const char **p, size_t *idx) { size_t l; char val_type = **p; mar_incr_ptr(MAR_CHR); switch (val_type) { case LUA_TBOOLEAN: lua_pushboolean(L, *(char*)*p); mar_incr_ptr(MAR_CHR); break; case LUA_TNUMBER: lua_pushnumber(L, *(lua_Number*)*p); mar_incr_ptr(MAR_I64); break; case MAR_TINT: lua_pushinteger(L, *(lua_Integer*)*p); mar_incr_ptr(MAR_I64); break; case LUA_TSTRING: mar_next_len(l, uint32_t); lua_pushlstring(L, *p, l); mar_incr_ptr(l); break; case LUA_TTABLE: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TVAL) { mar_next_len(l, uint32_t); lua_newtable(L); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_decode_table(L, *p, l, idx); mar_incr_ptr(l); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { luaL_error(L, "bad encoded data"); } break; } case LUA_TFUNCTION: { unsigned int nups; unsigned int i; mar_Buffer dec_buf; char tag = *(char*)*p; mar_incr_ptr(1); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else { mar_next_len(l, uint32_t); dec_buf.data = (char*)*p; dec_buf.size = l; dec_buf.head = l; dec_buf.seek = 0; lua_load(L, (lua_Reader)buf_read, &dec_buf, "=marshal", NULL); mar_incr_ptr(l); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_pushstring(L, MAR_ENV_IDX_KEY); lua_rawget(L, -2); if (lua_isnumber(L, -1)) { lua_pushglobaltable(L); lua_rawset(L, -3); } else { lua_pop(L, 1); } lua_pushstring(L, MAR_NUPS_IDX_KEY); lua_rawget(L, -2); nups = luaL_checknumber(L, -1); lua_pop(L, 1); for (i = 1; i <= nups; i++) { lua_rawgeti(L, -1, i); lua_setupvalue(L, -3, i); } lua_pop(L, 1); mar_incr_ptr(l); } break; } case LUA_TUSERDATA: { char tag = *(char*)*p; mar_incr_ptr(MAR_CHR); if (tag == MAR_TREF) { int ref; mar_next_len(ref, int); lua_rawgeti(L, SEEN_IDX, ref); } else if (tag == MAR_TUSR) { mar_next_len(l, uint32_t); lua_newtable(L); mar_decode_table(L, *p, l, idx); lua_rawgeti(L, -1, 1); lua_call(L, 0, 1); lua_remove(L, -2); lua_pushvalue(L, -1); lua_rawseti(L, SEEN_IDX, (*idx)++); mar_incr_ptr(l); } else { /* tag == MAR_TVAL */ lua_pushnil(L); } break; } case LUA_TNIL: case LUA_TTHREAD: lua_pushnil(L); break; default: luaL_error(L, "bad code"); } }
// Don't whine bout my gotos, lua api is a bitch, i had to! int CLuaClassDefs::Index ( lua_State* luaVM ) { lua_pushvalue ( luaVM, lua_upvalueindex ( 1 ) ); // ud, k, mt // First we look for a function lua_pushstring ( luaVM, "__class" ); // ud, k, mt, "__class" lua_rawget ( luaVM, -2 ); // ud, k, mt, __class table if ( !lua_istable ( luaVM, -1 ) ) { lua_pop ( luaVM, 1 ); // ud, k, mt goto searchparent; } lua_pushvalue ( luaVM, 2 ); // ud, k, mt, __class table, k lua_rawget ( luaVM, -2 ); // ud, k, mt, __class table, function lua_remove ( luaVM, -2 ); // ud, k, mt, function if ( lua_isfunction ( luaVM, -1 ) ) { // Found the function, clean up and return lua_remove ( luaVM, -2 ); // ud, k, function return 1; } lua_pop ( luaVM, 1 ); // ud, k, mt // Function not found, look for property lua_pushstring ( luaVM, "__get" ); // ud, k, mt, "__get" lua_rawget ( luaVM, -2 ); // ud, k, mt, __get table if ( !lua_istable ( luaVM, -1 ) ) { lua_pop ( luaVM, 1 ); // ud, k, mt goto searchparent; } lua_pushvalue ( luaVM, 2 ); // ud, k, mt, __get table, k lua_rawget ( luaVM, -2 ); // ud, k, mt, __get table, function lua_remove ( luaVM, -2 ); // ud, k, mt, function if ( lua_isfunction ( luaVM, -1 ) ) { // Found the property, lua_remove ( luaVM, -2 ); // ud, k, function lua_pushvalue ( luaVM, 1 ); // ud, k, function, ud lua_call ( luaVM, 1, 1 ); // ud, k, result return 1; } lua_pop ( luaVM, 1 ); // ud, k, mt searchparent: lua_pushstring ( luaVM, "__parent" ); // ud, k, mt, "__parent" lua_rawget ( luaVM, -2 ); // ud, k, mt, __parent table if ( lua_istable ( luaVM, -1 ) ) { lua_pushstring ( luaVM, "__index" ); // ud, k, mt, __parent table, "__index" lua_rawget ( luaVM, -2 ); // ud, k, mt, __parent table, function if ( lua_isfunction ( luaVM, -1 ) ) { lua_pushvalue ( luaVM, 1 ); // ud, k, mt, __parent table, function, ud lua_pushvalue ( luaVM, 2 ); // ud, k, mt, __parent table, function, ud, k lua_call ( luaVM, 2, 1 ); // ud, k, mt, __parent table, result lua_replace ( luaVM, -3 ); // ud, k, result, __parent table lua_pop ( luaVM, 1 ); // ud, k, result return 1; } lua_pop ( luaVM, 1 ); // ud, k, mt, __parent table } lua_pop ( luaVM, 2 ); // ud, k lua_pushnil ( luaVM ); return 1; }
static void mar_encode_value(lua_State *L, mar_Buffer *buf, int val, size_t *idx) { size_t l; int val_type = lua_type(L, val); if (lua_isinteger(L, val)) val_type = MAR_TINT; lua_pushvalue(L, val); buf_write(L, (const char*)&val_type, MAR_CHR, buf); switch (val_type) { case LUA_TBOOLEAN: { int int_val = lua_toboolean(L, -1); buf_write(L, (const char*)&int_val, MAR_CHR, buf); break; } case LUA_TSTRING: { const char *str_val = lua_tolstring(L, -1, &l); buf_write(L, (const char*)&l, MAR_I32, buf); buf_write(L, str_val, l, buf); break; } case LUA_TNUMBER: { lua_Number num_val = lua_tonumber(L, -1); buf_write(L, (const char*)&num_val, MAR_I64, buf); break; } case MAR_TINT: { lua_Integer num_val = lua_tointeger(L, -1); buf_write(L, (const char*)&num_val, MAR_I64, buf); break; } case LUA_TTABLE: { int tag, ref; lua_pushvalue(L, -1); lua_rawget(L, SEEN_IDX); if (!lua_isnil(L, -1)) { ref = lua_tointeger(L, -1); tag = MAR_TREF; buf_write(L, (const char*)&tag, MAR_CHR, buf); buf_write(L, (const char*)&ref, MAR_I32, buf); lua_pop(L, 1); } else { mar_Buffer rec_buf; lua_pop(L, 1); /* pop nil */ if (luaL_getmetafield(L, -1, "__persist")) { tag = MAR_TUSR; lua_pushvalue(L, -2); /* self */ lua_call(L, 1, 1); if (!lua_isfunction(L, -1)) { luaL_error(L, "__persist must return a function"); } lua_remove(L, -2); /* __persist */ lua_newtable(L); lua_pushvalue(L, -2); /* callback */ lua_rawseti(L, -2, 1); buf_init(L, &rec_buf); mar_encode_table(L, &rec_buf, idx); buf_write(L, (const char*)&tag, MAR_CHR, buf); buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); buf_write(L, rec_buf.data, rec_buf.head, buf); buf_done(L, &rec_buf); lua_pop(L, 1); } else { tag = MAR_TVAL; lua_pushvalue(L, -1); lua_pushinteger(L, (*idx)++); lua_rawset(L, SEEN_IDX); lua_pushvalue(L, -1); buf_init(L, &rec_buf); mar_encode_table(L, &rec_buf, idx); lua_pop(L, 1); buf_write(L, (const char*)&tag, MAR_CHR, buf); buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); buf_write(L, rec_buf.data,rec_buf.head, buf); buf_done(L, &rec_buf); } } break; } case LUA_TFUNCTION: { int tag, ref; lua_pushvalue(L, -1); lua_rawget(L, SEEN_IDX); if (!lua_isnil(L, -1)) { ref = lua_tointeger(L, -1); tag = MAR_TREF; buf_write(L, (const char*)&tag, MAR_CHR, buf); buf_write(L, (const char*)&ref, MAR_I32, buf); lua_pop(L, 1); } else { mar_Buffer rec_buf; unsigned int i; lua_Debug ar; lua_pop(L, 1); /* pop nil */ lua_pushvalue(L, -1); lua_getinfo(L, ">nuS", &ar); if (ar.what[0] != 'L') { luaL_error(L, "attempt to persist a C function '%s'", ar.name); } tag = MAR_TVAL; lua_pushvalue(L, -1); lua_pushinteger(L, (*idx)++); lua_rawset(L, SEEN_IDX); lua_pushvalue(L, -1); buf_init(L, &rec_buf); lua_dump(L, (lua_Writer)buf_write, &rec_buf, true); buf_write(L, (const char*)&tag, MAR_CHR, buf); buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); buf_write(L, rec_buf.data, rec_buf.head, buf); buf_done(L, &rec_buf); lua_pop(L, 1); lua_createtable(L, ar.nups, 0); for (i = 1; i <= ar.nups; i++) { const char* upvalue_name = lua_getupvalue(L, -2, i); if (strcmp("_ENV", upvalue_name) == 0) { lua_pop(L, 1); // Mark where _ENV is expected. lua_pushstring(L, MAR_ENV_IDX_KEY); lua_pushinteger(L, i); lua_rawset(L, -3); } else { lua_rawseti(L, -2, i); } } lua_pushstring(L, MAR_NUPS_IDX_KEY); lua_pushnumber(L, ar.nups); lua_rawset(L, -3); buf_init(L, &rec_buf); mar_encode_table(L, &rec_buf, idx); buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); buf_write(L, rec_buf.data, rec_buf.head, buf); buf_done(L, &rec_buf); lua_pop(L, 1); } break; } case LUA_TUSERDATA: { int tag, ref; lua_pushvalue(L, -1); lua_rawget(L, SEEN_IDX); if (!lua_isnil(L, -1)) { ref = lua_tointeger(L, -1); tag = MAR_TREF; buf_write(L, (const char*)&tag, MAR_CHR, buf); buf_write(L, (const char*)&ref, MAR_I32, buf); lua_pop(L, 1); } else { mar_Buffer rec_buf; lua_pop(L, 1); /* pop nil */ if (luaL_getmetafield(L, -1, "__persist")) { tag = MAR_TUSR; lua_pushvalue(L, -2); lua_pushinteger(L, (*idx)++); lua_rawset(L, SEEN_IDX); lua_pushvalue(L, -2); lua_call(L, 1, 1); if (!lua_isfunction(L, -1)) { luaL_error(L, "__persist must return a function"); } lua_newtable(L); lua_pushvalue(L, -2); lua_rawseti(L, -2, 1); lua_remove(L, -2); buf_init(L, &rec_buf); mar_encode_table(L, &rec_buf, idx); buf_write(L, (const char*)&tag, MAR_CHR, buf); buf_write(L, (const char*)&rec_buf.head, MAR_I32, buf); buf_write(L, rec_buf.data, rec_buf.head, buf); buf_done(L, &rec_buf); } else { luaL_error(L, "attempt to encode userdata (no __persist hook)"); } lua_pop(L, 1); } break; } case LUA_TNIL: break; default: luaL_error(L, "invalid value type (%s)", lua_typename(L, val_type)); } lua_pop(L, 1); }
int cLuaState::CallFunctionWithForeignParams( const AString & a_FunctionName, cLuaState & a_SrcLuaState, int a_SrcParamStart, int a_SrcParamEnd ) { ASSERT(IsValid()); ASSERT(a_SrcLuaState.IsValid()); // Store the stack position before any changes int OldTop = lua_gettop(m_LuaState); // Push the function to call, including the error handler: if (!PushFunction(a_FunctionName.c_str())) { LOGWARNING("Function '%s' not found", a_FunctionName.c_str()); lua_pop(m_LuaState, 2); return -1; } // Copy the function parameters to the target state if (CopyStackFrom(a_SrcLuaState, a_SrcParamStart, a_SrcParamEnd) < 0) { // Something went wrong, fix the stack and exit lua_pop(m_LuaState, 2); m_NumCurrentFunctionArgs = -1; m_CurrentFunctionName.clear(); return -1; } // Call the function, with an error handler: int s = lua_pcall(m_LuaState, a_SrcParamEnd - a_SrcParamStart + 1, LUA_MULTRET, OldTop + 1); if (ReportErrors(s)) { LOGWARN("Error while calling function '%s' in '%s'", a_FunctionName.c_str(), m_SubsystemName.c_str()); // Fix the stack. // We don't know how many values have been pushed, so just get rid of any that weren't there initially int CurTop = lua_gettop(m_LuaState); if (CurTop > OldTop) { lua_pop(m_LuaState, CurTop - OldTop); } // Reset the internal checking mechanisms: m_NumCurrentFunctionArgs = -1; m_CurrentFunctionName.clear(); // Make Lua think everything is okay and return 0 values, so that plugins continue executing. // The failure is indicated by the zero return values. return 0; } // Reset the internal checking mechanisms: m_NumCurrentFunctionArgs = -1; m_CurrentFunctionName.clear(); // Remove the error handler from the stack: lua_remove(m_LuaState, OldTop + 1); // Return the number of return values: return lua_gettop(m_LuaState) - OldTop; }
void dispatchEvent(int type, void *event) { luaL_rawgetptr(L, LUA_REGISTRYINDEX, &keyWeak); luaL_rawgetptr(L, -1, this); if (lua_isnil(L, -1)) { lua_pop(L, 2); return; } lua_getfield(L, -1, "dispatchEvent"); lua_pushvalue(L, -2); lua_getglobal(L, "Event"); lua_getfield(L, -1, "new"); lua_remove(L, -2); switch (type) { case GHID_KEY_DOWN_EVENT: lua_pushstring(L, KEY_DOWN); break; case GHID_KEY_UP_EVENT: lua_pushstring(L, KEY_UP); break; case GHID_RIGHT_JOYSTICK_EVENT: lua_pushstring(L, RIGHT_JOYSTICK); break; case GHID_LEFT_JOYSTICK_EVENT: lua_pushstring(L, LEFT_JOYSTICK); break; case GHID_RIGHT_TRIGGER_EVENT: lua_pushstring(L, RIGHT_TRIGGER); break; case GHID_LEFT_TRIGGER_EVENT: lua_pushstring(L, LEFT_TRIGGER); break; case GHID_AXIS_JOYSTICK_EVENT: lua_pushstring(L, AXIS_JOYSTICK); break; case GHID_CONNECTED_EVENT: lua_pushstring(L, CONNECTED); break; case GHID_DISCONNECTED_EVENT: lua_pushstring(L, DISCONNECTED); break; } lua_call(L, 1, 1); if (type == GHID_KEY_DOWN_EVENT || type == GHID_KEY_UP_EVENT) { ghid_KeyEvent *event2 = (ghid_KeyEvent*)event; lua_pushnumber(L, event2->keyCode); lua_setfield(L, -2, "keyCode"); lua_pushnumber(L, event2->realCode); lua_setfield(L, -2, "realCode"); lua_pushnumber(L, event2->playerId); lua_setfield(L, -2, "playerId"); } else if (type == GHID_RIGHT_JOYSTICK_EVENT || type == GHID_LEFT_JOYSTICK_EVENT) { ghid_JoystickEvent *event2 = (ghid_JoystickEvent*)event; lua_pushnumber(L, event2->x); lua_setfield(L, -2, "x"); lua_pushnumber(L, event2->y); lua_setfield(L, -2, "y"); lua_pushnumber(L, event2->angle); lua_setfield(L, -2, "angle"); lua_pushnumber(L, event2->strength); lua_setfield(L, -2, "strength"); lua_pushnumber(L, event2->playerId); lua_setfield(L, -2, "playerId"); } else if (type == GHID_RIGHT_TRIGGER_EVENT || type == GHID_LEFT_TRIGGER_EVENT) { ghid_TriggerEvent *event2 = (ghid_TriggerEvent*)event; lua_pushnumber(L, event2->strength); lua_setfield(L, -2, "strength"); lua_pushnumber(L, event2->playerId); lua_setfield(L, -2, "playerId"); } else if (type == GHID_AXIS_JOYSTICK_EVENT) { ghid_JoystickEvent *event2 = (ghid_JoystickEvent*)event; lua_pushnumber(L, event2->playerId); lua_setfield(L, -2, "playerId"); lua_pushnumber(L, event2->strength); lua_setfield(L, -2, "strength"); lua_pushnumber(L, event2->angle); lua_setfield(L, -2, "axis"); } else if (type == GHID_CONNECTED_EVENT || type == GHID_DISCONNECTED_EVENT) { ghid_DeviceEvent *event2 = (ghid_DeviceEvent*)event; lua_pushnumber(L, event2->playerId); lua_setfield(L, -2, "playerId"); } lua_call(L, 2, 0); lua_pop(L, 2); }
static int l_signal(lua_State *L) { int args = lua_gettop(L); int t, sig; /* type, signal */ /* get type of signal */ luaL_checkany(L, 1); t = lua_type(L, 1); if (t == LUA_TNUMBER) sig = (int) lua_tonumber(L, 1); else if (t == LUA_TSTRING) { lua_pushstring(L, LUA_SIGNAL); lua_gettable(L, LUA_REGISTRYINDEX); lua_pushvalue(L, 1); lua_gettable(L, -2); if (!lua_isnumber(L, -1)) luaL_error(L, "invalid signal string"); sig = (int) lua_tonumber(L, -1); lua_pop(L, 1); /* get rid of number we pushed */ } else luaL_checknumber(L, 1); /* will always error, with good error msg */ /* set handler */ if (args == 1 || lua_isnil(L, 2)) /* clear handler */ { lua_pushstring(L, LUA_SIGNAL); lua_gettable(L, LUA_REGISTRYINDEX); lua_pushnumber(L, sig); lua_gettable(L, -2); /* return old handler */ lua_pushnumber(L, sig); lua_pushnil(L); lua_settable(L, -4); lua_remove(L, -2); /* remove LUA_SIGNAL table */ signal(sig, SIG_DFL); } else { luaL_checktype(L, 2, LUA_TFUNCTION); lua_pushstring(L, LUA_SIGNAL); lua_gettable(L, LUA_REGISTRYINDEX); lua_pushnumber(L, sig); lua_pushvalue(L, 2); lua_settable(L, -3); /* Set the state for the handler */ Lsig = L; if (lua_toboolean(L, 3)) /* c hook? */ { if (signal(sig, handle) == SIG_ERR) lua_pushboolean(L, 0); else lua_pushboolean(L, 1); } else /* lua_hook */ { if (signal(sig, handle) == SIG_ERR) lua_pushboolean(L, 0); else lua_pushboolean(L, 1); } } return 1; }
/* 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) { lua_pushvalue(L,1); class_table_get_index(L); return 1; } lua_pushnil(L); return 1; }
void ReadScriptDescriptor::ClearStack(uint32 levels_to_clear) { _open_tables.clear(); for(uint32 i = 0; i < levels_to_clear; ++i) lua_remove(_lstack, 0); }
/* Newindex function * It first searches for a C/C++ varaible to be set. * Then, it either stores it in the alternative ubox table (in the case it is * an object) or in the own table (that represents the class or module). */ static int class_newindex_event (lua_State* L) { int t = lua_type(L,1); if (t == LUA_TUSERDATA) { /* Try accessing a C/C++ variable to be set */ lua_getmetatable(L,1); while (lua_istable(L,-1)) /* stack: t k v mt */ { if (lua_isnumber(L,2)) /* check if key is a numeric value */ { /* try operator[] */ lua_pushstring(L,".seti"); lua_rawget(L,-2); /* stack: obj key mt func */ if (lua_isfunction(L,-1)) { lua_pushvalue(L,1); lua_pushvalue(L,2); lua_pushvalue(L,3); lua_call(L,3,0); return 0; } } else { lua_pushstring(L,".set"); lua_rawget(L,-2); /* stack: t k v mt tset */ if (lua_istable(L,-1)) { lua_pushvalue(L,2); lua_rawget(L,-2); /* stack: t k v mt tset func */ if (lua_iscfunction(L,-1)) { lua_pushvalue(L,1); lua_pushvalue(L,3); lua_call(L,2,0); return 0; } lua_pop(L,1); /* stack: t k v mt tset */ } lua_pop(L,1); /* stack: t k v mt */ if (!lua_getmetatable(L,-1)) /* stack: t k v mt mt */ lua_pushnil(L); lua_remove(L,-2); /* stack: t k v mt */ } } lua_settop(L,3); /* stack: t k v */ /* then, store as a new field */ storeatubox(L,1); } else if (t== LUA_TTABLE) { lua_getmetatable(L,1); /* stack: t k v mt */ lua_pushstring(L,".set"); lua_rawget(L,-2); /* stack: t k v mt tset */ if (lua_istable(L,-1)) { lua_pushvalue(L,2); /* stack: t k v mt tset k */ lua_rawget(L,-2); if (lua_iscfunction(L,-1)) { /* ... func */ lua_pushvalue(L,1); /* ... func t */ lua_pushvalue(L,3); /* ... func t v */ lua_call(L,2,0); return 0; } } lua_settop(L,3); class_backup_before_newindex(L); lua_settop(L,3); lua_getmetatable(L,1); /* stack: t k v mt */ lua_replace(L, 1); /* stack: mt k v */ lua_rawset(L,1); } return 0; }
static int luaA_sysctl_get(lua_State *L) { int nlen; int i; int oid[CTL_MAXNAME]; int ctltype; u_int kind; size_t len; size_t intlen; uintmax_t umv; intmax_t mv; char fmt[BUFSIZ]; char buf[BUFSIZ]; char *val, *oval, *p; int (*func)(lua_State *, int, void *); bzero(fmt, BUFSIZ); bzero(buf, BUFSIZ); /* get first argument from lua */ len = strlcpy(buf, luaL_checkstring(L, 1), sizeof(buf)); if (len >= sizeof(buf)) return (luaL_error(L, "oid too long")); nlen = name2oid(buf, oid); if (nlen < 0) return (luaL_error(L, "%s: unknown iod", buf)); if (oidfmt(oid, nlen, fmt, sizeof(fmt), &kind) != 0) return (luaL_error(L, "couldn't find format of oid '%s'", buf)); if ((kind & CTLTYPE) == CTLTYPE_NODE) return (luaL_error(L, "can't handle CTLTYPE_NODE")); /* find an estimate of how much we need for this var */ len = 0; (void)sysctl(oid, nlen, NULL, &len, NULL, 0); len += len; /* we want to be sure :-) */ val = oval = malloc(len + 1); if (val == NULL) return (luaL_error(L, "malloc failed")); i = sysctl(oid, nlen, val, &len, NULL, 0); if (i || !len) { free(oval); return (luaL_error(L, "sysctl failed")); } val[len] = '\0'; p = val; ctltype = (kind & CTLTYPE); intlen = ctl_size[ctltype]; switch (ctltype) { case CTLTYPE_STRING: lua_pushstring(L, p); break; case CTLTYPE_INT: /* FALLTHROUGH */ case CTLTYPE_UINT: /* FALLTHROUGH */ case CTLTYPE_LONG: /* FALLTHROUGH */ case CTLTYPE_ULONG: /* FALLTHROUGH */ #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: #else case CTLTYPE_S64: /* FALLTHROUGH */ case CTLTYPE_U64: #endif /* an intlen of 0 or less will make us loop indefinitely */ if (intlen <= 0) { free(oval); return (luaL_error(L, "sysctl error (intlen == %zd)", intlen)); } i = 0; lua_newtable(L); while (len >= intlen) { i++; switch (ctltype) { case CTLTYPE_INT: /* FALLTHROUGH */ case CTLTYPE_UINT: umv = *(u_int *)p; mv = *(int *)p; break; case CTLTYPE_LONG: /* FALLTHROUGH */ case CTLTYPE_ULONG: umv = *(u_long *)p; mv = *(long *)p; break; #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: umv = *(u_quad_t *)p; mv = *(quad_t *)p; #else case CTLTYPE_S64: /* FALLTHROUGH */ case CTLTYPE_U64: umv = *(uint64_t *)p; mv = *(int64_t *)p; #endif break; default: return (luaL_error(L, "sysctl error (bug)")); /* NOTREACHED */ } lua_pushinteger(L, i); switch (ctltype) { case CTLTYPE_INT: /* FALLTHROUGH */ case CTLTYPE_LONG: lua_pushinteger(L, mv); break; case CTLTYPE_UINT: /* FALLTHROUGH */ case CTLTYPE_ULONG: lua_pushinteger(L, umv); break; #if __FreeBSD_version < 900000 case CTLTYPE_QUAD: lua_pushnumber(L, mv); break; #else case CTLTYPE_S64: lua_pushnumber(L, mv); break; case CTLTYPE_U64: lua_pushnumber(L, umv); break; #endif default: return (luaL_error(L, "sysctl error (bug)")); /* NOTREACHED */ } lua_settable(L, -3); len -= intlen; p += intlen; } if (i == 1) { lua_pushinteger(L, i); lua_gettable(L, -2); lua_remove(L, lua_gettop(L) - 1); /* remove table */ } break; case CTLTYPE_OPAQUE: if (strcmp(fmt, "S,clockinfo") == 0) func = S_clockinfo; else if (strcmp(fmt, "S,loadavg") == 0) func = S_loadavg; else if (strcmp(fmt, "S,timeval") == 0) func = S_timeval; else if (strcmp(fmt, "S,vmtotal") == 0) func = S_vmtotal; else if (strcmp(fmt, "T,dev_t") == 0) func = T_dev_t; else func = NULL; if (func) { (*func)(L, len, val); break; } /* FALLTHROUGH */ default: free(oval); return (luaL_error(L, "unknown CTLTYPE: fmt=%s ctltype=%d", fmt, ctltype)); } free(oval); lua_pushstring(L, fmt); return (2); /* two returned value */ }
void LuaInstance::Remove(int index) const { lua_remove(m_state, index); }
void siplua_register_watch_cclosures(lua_State *L) { lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_openlib(L, NULL, siplua_watch_mylib, 0); lua_remove(L, -1); }
/** * Set the premake.path variable, pulling from the --scripts argument * and PREMAKE_PATH environment variable if present. */ static void build_premake_path(lua_State* L) { int top; const char* value; lua_getglobal(L, "premake"); top = lua_gettop(L); /* Start by searching the current working directory */ lua_pushstring(L, "."); /* The --scripts argument goes next, if present */ if (scripts_path) { lua_pushstring(L, ";"); lua_pushstring(L, scripts_path); } /* Then the PREMAKE_PATH environment variable */ value = getenv("PREMAKE_PATH"); if (value) { lua_pushstring(L, ";"); lua_pushstring(L, value); } /* Then in ~/.premake */ lua_pushstring(L, ";"); lua_getglobal(L, "_USER_HOME_DIR"); lua_pushstring(L, "/.premake"); /* In the user's Application Support folder */ #if defined(PLATFORM_MACOSX) lua_pushstring(L, ";"); lua_getglobal(L, "_USER_HOME_DIR"); lua_pushstring(L, "/Library/Application Support/Premake"); #endif /* In the /usr tree */ lua_pushstring(L, ";/usr/local/share/premake;/usr/share/premake"); /* Put it all together */ lua_concat(L, lua_gettop(L) - top); /* Match Lua's package.path; use semicolon separators */ #if !defined(PLATFORM_WINDOWS) lua_getglobal(L, "string"); lua_getfield(L, -1, "gsub"); lua_pushvalue(L, -3); lua_pushstring(L, ":"); lua_pushstring(L, ";"); lua_call(L, 3, 1); /* remove the string global table */ lua_remove(L, -2); /* remove the previously concatonated result */ lua_remove(L, -2); #endif /* Store it in premake.path */ lua_setfield(L, -2, "path"); /* Remove the premake namespace table */ lua_pop(L, 1); }
LUALIB_API void luaL_pushresult (luaL_Buffer *B) { lua_State *L = B->L; lua_pushlstring(L, B->b, B->n); if (buffonstack(B)) lua_remove(L, -2); /* remove old buffer */ }
void LuaUtils::PushCurrentFuncEnv(lua_State* L, const char* caller) { PushCurrentFunc(L, caller); PushFunctionEnv(L, caller, -1); lua_remove(L, -2); // remove the function }
int w_World_getCallbacks(lua_State *L) { World *t = luax_checkworld(L, 1); lua_remove(L, 1); return t->getCallbacks(L); }
static int errfile (lua_State *L, int fnameindex) { const char *filename = lua_tostring(L, fnameindex) + 1; lua_pushfstring(L, "cannot read %s: %s", filename, strerror(errno)); lua_remove(L, fnameindex); return LUA_ERRFILE; }
int w_World_getGravity(lua_State *L) { World *t = luax_checkworld(L, 1); lua_remove(L, 1); return t->getGravity(L); }
int script_func_exec(const char *func, const char *sig, ...) { int lev = 1; /* `func` is global function */ int err = 0; size_t tok_len = 0; const char *cur_mod = func, *mod; char module[MAX_MODULE_NAME_LENGTH]; lua_getglobal(L, "_G"); if (!lua_istable(L, -1)) { lua_pop(L, lev); LOG_ERROR("script", "%s", "Global table is NOT available."); return SCRIPT_RC_ERROR; } while ((mod = strchr(cur_mod, '.'))) { tok_len = mod - cur_mod; strncpy(module, cur_mod, tok_len); module[tok_len] = '\0'; cur_mod = mod + 1; lua_getfield(L, -1, module); ++lev; if (!lua_istable(L, -1)) { lua_pop(L, lev); LOG_ERROR("script", "`%s()` is NOT recognized as a Lua function.", func); return SCRIPT_RC_ERROR; } } lua_getfield(L, -1, cur_mod); /* function */ if (!lua_isfunction(L, -1)) { lua_pop(L, lev + 1); LOG_ERROR("script", "`%s()` is NOT recognized as a Lua function.", func); return SCRIPT_RC_ERROR; } va_list args; va_start(args, sig); int argc = 0; /* parse input arguments */ for (; sig && *sig && *sig != '>'; ++sig, ++argc) { switch (*sig) { case 'i': /* integer */ lua_pushnumber(L, va_arg(args, int)); break; case 's': /* string */ lua_pushstring(L, va_arg(args, char *)); break; case 'f': /* double */ lua_pushnumber(L, va_arg(args, double)); break; default: /* double */ LOG_ERROR("script", "invalid option (%c)", *sig); lua_pop(L, lev + argc); return SCRIPT_RC_ERROR; } } int handler = lua_gettop(L) - argc; lua_pushcfunction(L, script_traceback); lua_insert(L, handler); err = lua_pcall(L, argc, LUA_MULTRET, handler); lua_remove(L, handler); va_end(args); if (err) { return script_error(L); } lua_pop(L, lev); return SCRIPT_RC_OK; }
int pklua_lua_pkm_get_metrics(lua_State* L) { struct pk_global_state* state = &pk_state; pk_log(PK_LOG_LUA_DEBUG, "pklua_lua_pkm_get_metrics(%p)", L); int n = lua_gettop(L); if (n != 1 || !lua_istable(L, 1)) { lua_pushstring(L, "Incorrect arguments in get_metrics"); return lua_error(L); } lua_getfield(L, 1, "_pkm"); if (!lua_islightuserdata(L, -1)) { lua_pushstring(L, "Incorrect arguments in get_metrics (2)"); return lua_error(L); } struct pk_manager* manager = lua_touserdata(L, -1); lua_remove(L, -1); lua_newtable(L); int metrics = lua_gettop(L); /* Relatives offsets would break below */ lua_pushstring(L, PK_VERSION); lua_setfield(L, metrics, "libpagekite_version"); #define PKM_INT(s, n) lua_pushinteger(L, s->n);\ lua_setfield(L, metrics, #s"_"#n) #define PKM_STR(s, n) lua_pushstring(L, (s->n == NULL) ? "(null)" : s->n);\ lua_setfield(L, metrics, #s"_"#n) PKM_INT(manager, status); PKM_INT(manager, last_world_update); PKM_INT(manager, next_tick); PKM_INT(manager, enable_timer); PKM_INT(manager, last_dns_update); PKM_INT(manager, kite_max); PKM_INT(manager, tunnel_max); PKM_INT(manager, be_conn_max); PKM_INT(manager, fancy_pagekite_net_rejection); PKM_INT(manager, enable_watchdog); PKM_INT(manager, want_spare_frontends); PKM_INT(manager, housekeeping_interval_min); PKM_INT(manager, housekeeping_interval_max); PKM_INT(manager, check_world_interval); PKM_STR(manager, dynamic_dns_url); PKM_INT(state, live_streams); PKM_INT(state, live_tunnels); PKM_INT(state, live_listeners); PKM_STR(state, app_id_short); PKM_STR(state, app_id_long); PKM_INT(state, quota_days); PKM_INT(state, quota_conns); PKM_INT(state, quota_mb); /* Copy Lua metrics from master Lua context */ pk_lua_t* mgr_lua; if ((mgr_lua = pklua_lock_lua(manager->lua)) != NULL) { lua_State* ML = mgr_lua->lua; lua_getfield(ML, LUA_GLOBALSINDEX, "pklua"); lua_getfield(ML, -1, "metrics"); /* ML stack: -1=metrics, -2=pklua */ lua_pushnil(ML); while (lua_next(ML, -2)) { /* copy key and value so lua_tostring doesn't corrupt */ lua_pushvalue(ML, -2); lua_pushvalue(ML, -2); /* ML stack: -1=value copy, -2=key copy, -3=value, -4=key, -5=metrics */ lua_pushinteger(L, lua_tointeger(ML, -1)); lua_setfield(L, metrics, lua_tostring(ML, -2)); lua_pop(ML, 3); /* ML stack: -1=key, -2=metrics */ } lua_remove(ML, -1); lua_remove(ML, -1); pklua_unlock_lua(mgr_lua); } /* L stack: -1 = new table */ return 1; }
int get_pgfunc(lua_State *L) { Lua_pgfunc *lf; Pgfunc_options opt; MemoryContext m; const char* reg_name = NULL; HeapTuple proctup; Form_pg_proc proc; int luasrc = 0; Oid funcid = 0; BEGINLUA; opt.only_internal = true; opt.throwable = true; if (lua_gettop(L) == 2){ luaL_checktype(L, 2, LUA_TTABLE); parse_options(L, &opt); }else if (lua_gettop(L) != 1){ return luaL_error(L, "pgfunc(text): wrong arguments"); } if(lua_type(L, 1) == LUA_TSTRING){ reg_name = luaL_checkstring(L, 1); m = MemoryContextSwitchTo(tmpcontext); PG_TRY(); { funcid = DatumGetObjectId(DirectFunctionCall1(regprocedurein, CStringGetDatum(reg_name))); } PG_CATCH();{} PG_END_TRY(); MemoryContextSwitchTo(m); MemoryContextReset(tmpcontext); }else if (lua_type(L, 1) == LUA_TNUMBER){ funcid = luaL_checkinteger(L, 1); } if (!OidIsValid(funcid)){ if (reg_name) return luaL_error(L,"failed to register %s", reg_name); return luaL_error(L,"failed to register function with oid %d", funcid); } proctup = SearchSysCache1(PROCOID, ObjectIdGetDatum(funcid)); if (!HeapTupleIsValid(proctup)){ return luaL_error(L,"cache lookup failed for function %d", funcid); } proc = (Form_pg_proc) GETSTRUCT(proctup); luasrc = ((proc->prolang == get_pllua_oid()) || (proc->prolang == get_plluau_oid())); if ( opt.only_internal &&(proc->prolang != INTERNALlanguageId) &&(!luasrc) ){ ReleaseSysCache(proctup); return luaL_error(L, "supported only SQL/internal functions"); } lf = (Lua_pgfunc *)lua_newuserdata(L, sizeof(Lua_pgfunc)); /*make it g/collected*/ luaP_getfield(L, pg_func_type_name); lua_setmetatable(L, -2); lf->prorettype = proc->prorettype; lf->funcid = funcid; lf->options = opt; { Oid *argtypes; char **argnames; char *argmodes; int argc; MemoryContext cur = CurrentMemoryContext; MemoryContextSwitchTo(tmpcontext); argc = get_func_arg_info(proctup, &argtypes, &argnames, &argmodes); MemoryContextSwitchTo(get_common_ctx()); lf->numargs = argc; lf->argtypes = (Oid*)palloc(argc * sizeof(Oid)); memcpy(lf->argtypes, argtypes, argc * sizeof(Oid)); MemoryContextSwitchTo(cur); MemoryContextReset(tmpcontext); } if (luasrc){ bool isnull; text *t; const char *s; luaL_Buffer b; int pcall_result; Datum prosrc; if((lf->numargs != 1) || (lf->argtypes[0] != INTERNALOID) || (lf->prorettype != INTERNALOID)){ luaL_error(L, "pgfunc accepts only 'internal' pllua/u functions with internal argument"); } prosrc = SysCacheGetAttr(PROCOID, proctup, Anum_pg_proc_prosrc, &isnull); if (isnull) elog(ERROR, "[pgfunc]: null lua prosrc"); luaL_buffinit(L, &b); luaL_addstring(&b,"do "); t = DatumGetTextP(prosrc); luaL_addlstring(&b, VARDATA(t), VARSIZE(t) - VARHDRSZ); luaL_addstring(&b, " end"); luaL_pushresult(&b); s = lua_tostring(L, -1); ReleaseSysCache(proctup); clean_pgfuncinfo(lf); if (luaL_loadbuffer(L, s, strlen(s), "pgfunc chunk")) luaL_error(L, "compile"); lua_remove(L, -2); /*delete source element*/ pcall_result = lua_pcall(L, 0, 1, 0); lua_remove(L, -2); /*delete chunk*/ if(pcall_result == 0){ ENDLUAV(1); return 1; } if( pcall_result == LUA_ERRRUN) luaL_error(L,"%s %s","Runtime error:",lua_tostring(L, -1)); else if(pcall_result == LUA_ERRMEM) luaL_error(L,"%s %s","Memory error:",lua_tostring(L, -1)); else if(pcall_result == LUA_ERRERR) luaL_error(L,"%s %s","Error:",lua_tostring(L, -1)); return luaL_error(L, "pgfunc unknown error"); } if(proc->proretset) { lua_pushcclosure(L, pgfunc_rows, 1); } else { fmgr_info(funcid, &lf->fi); lua_pushcclosure(L, pg_callable_func, 1); } ReleaseSysCache(proctup); ENDLUAV(1); return 1; }