static int proc_exec(lua_State *L) { apr_status_t status; lua_apr_proc *process; const char *p, **args; int i, nargs = 0; lua_settop(L, 2); process = proc_check(L, 1); if (!lua_isnoneornil(L, 2)) { luaL_checktype(L, 2, LUA_TTABLE); nargs = lua_objlen(L, 2); } /* Allocate and initialize the array of arguments. */ args = apr_palloc(process->memory_pool, sizeof args[0] * (nargs + 2)); if (args == NULL) return push_error_memory(L); args[0] = apr_filepath_name_get(process->path); args[nargs+1] = NULL; /* Copy the arguments? */ if (nargs > 0) { for (i = 0; i <= nargs; i++) { lua_pushinteger(L, i); lua_gettable(L, 2); p = lua_tostring(L, -1); if (p != NULL) /* argument */ args[i] = apr_pstrdup(process->memory_pool, p); else if (i != 0) /* invalid value */ luaL_argcheck(L, 0, 2, lua_pushfstring(L, "invalid value at index %d", i)); lua_pop(L, 1); } } /* Create the child process using the given command line arguments. */ status = apr_proc_create(&process->handle, process->path, args, process->env, process->attr, process->memory_pool); return push_status(L, status); }
static int ime_join_string(lua_State* L){ luaL_Buffer buf; size_t vec_len; size_t i; const char * sep; const char * str; luaL_checktype(L, 1, LUA_TTABLE); sep = luaL_checklstring(L, 2, NULL); vec_len = lua_objlen(L, 1); if ( 0 == vec_len ){ lua_pop(L, 2); lua_pushliteral(L, ""); return 1; } luaL_buffinit(L, &buf); for ( i = 1; i < vec_len; ++i){ lua_pushinteger(L, i); lua_gettable(L, 1); str = luaL_checklstring(L, 3, NULL); luaL_addstring(&buf, str); lua_pop(L, 1); luaL_addstring(&buf, sep); } /* add tail of string list */ lua_pushinteger(L, i); lua_gettable(L, 1); str = luaL_checklstring(L, 3, NULL); luaL_addstring(&buf, str); lua_pop(L, 1); /* remove the args. */ lua_pop(L, 2); luaL_pushresult(&buf); return 1; }
/** * \brief Moves events from the event queue to Lua. * * Events are added to a queue and pushed to scripts separately. This * prevents the engine code from triggering garbage collection. That * is necessary to avoid arbitrary objects being deleted during the * physics update or other critical loops. * * \param self Program. */ void limai_program_pump_events ( LIMaiProgram* self) { int count; LIMaiEvent* event; lua_State* lua; /* Get the event queue. */ lua = liscr_script_get_lua (self->script); lua_getglobal (lua, "__events"); if (lua_type (lua, -1) != LUA_TTABLE) { lua_pop (lua, 1); lua_newtable (lua); lua_pushvalue (lua, -1); lua_setglobal (lua, "__events"); } /* Get the existing event count. */ #if LUA_VERSION_NUM > 501 count = lua_rawlen (lua, -1); #else count = lua_objlen (lua, -1); #endif /* Append events to the table. */ while (1) { event = limai_program_pop_event (self); if (event == NULL) break; lua_pushnumber (lua, ++count); limai_event_write_script (event, self->script); limai_event_free (event); lua_settable (lua, -3); } /* Pop the table from the stack. */ lua_pop (lua, 1); }
static int parse(lua_State *L) { const char* id = luaT_typenameid(L, "torch.FloatTensor"); //Get float THFloatTensor *tensor = (THFloatTensor*) luaT_checkudata(L, 1, id); //Check if float float *input_data = THFloatTensor_data(tensor); //Pointer to tensor region float threshold = lua_tonumber(L, 2); //Threshold sent by lua int table_blobs = 3; int idx = lua_objlen(L, 3) + 1; float scale = lua_tonumber(L, 4); //Which scale was this called for? // loop over pixels int x,y; for (y=0; y<tensor->size[0]; y++) { for (x=0; x<tensor->size[1]; x++) { float val = THFloatTensor_get2d(tensor, y, x); if (val > threshold) { // entry = {} lua_newtable(L); int entry = lua_gettop(L); // entry[1] = x lua_pushnumber(L, x); lua_rawseti(L, entry, 1); // entry[2] = y lua_pushnumber(L, y); lua_rawseti(L, entry, 2); // entry[3] = scale lua_pushnumber(L, scale); lua_rawseti(L, entry, 3); // blobs[idx] = entry; idx = idx + 1 lua_rawseti(L, table_blobs, idx++); } } } return 1; }
int MeshBinder::setTextureCoordinates(lua_State *L) { Binder binder(L); GMesh *mesh = static_cast<GMesh*>(binder.getInstance("Mesh", 1)); if (lua_type(L, 2) == LUA_TTABLE) { int n = lua_objlen(L, 2); for (int k = 0; k < n/3; ++k) { lua_rawgeti(L, 2, k * 3 + 1); int i = luaL_checkinteger(L, -1) - 1; lua_pop(L, 1); lua_rawgeti(L, 2, k * 3 + 2); float u = luaL_checknumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, 2, k * 3 + 3); float v = luaL_checknumber(L, -1); lua_pop(L, 1); mesh->setTextureCoordinate(i, u, v); } } else { int n = lua_gettop(L) - 1; for (int k = 0; k < n/3; ++k) { int i = luaL_checkinteger(L, k * 3 + 2) - 1; float u = luaL_checknumber(L, k * 3 + 3); float v = luaL_checknumber(L, k * 3 + 4); mesh->setTextureCoordinate(i, u, v); } } return 0; }
int MeshBinder::setColors(lua_State *L) { Binder binder(L); GMesh *mesh = static_cast<GMesh*>(binder.getInstance("Mesh", 1)); if (lua_type(L, 2) == LUA_TTABLE) { int n = lua_objlen(L, 2); for (int k = 0; k < n/3; ++k) { lua_rawgeti(L, 2, k * 3 + 1); int i = luaL_checkinteger(L, -1) - 1; lua_pop(L, 1); lua_rawgeti(L, 2, k * 3 + 2); unsigned int color = luaL_checkinteger(L, -1); lua_pop(L, 1); lua_rawgeti(L, 2, k * 3 + 3); float alpha = luaL_checknumber(L, -1); lua_pop(L, 1); mesh->setColor(i, color, alpha); } } else { int n = lua_gettop(L) - 1; for (int k = 0; k < n/3; ++k) { int i = luaL_checkinteger(L, k * 3 + 2) - 1; unsigned int color = luaL_checkinteger(L, k * 3 + 3); float alpha = luaL_checknumber(L, k * 3 + 4); mesh->setColor(i, color, alpha); } } return 0; }
int plot_xaxis_hol_set (lua_State *L) { sg_plot *p = object_check<sg_plot>(L, 1, GS_PLOT); double delta = lua_tonumber(L, 2); if (!lua_istable(L, 3)) return luaL_error(L, "expect labels table specification"); ptr_list<factor_labels>* hol = p->get_xaxis_hol(); bool create_hol = (hol == 0); if (create_hol) hol = new ptr_list<factor_labels>(); factor_labels* fl = new factor_labels(delta); int n = lua_objlen(L, 3); for (int k = 1; k <= n; k += 2) { lua_rawgeti(L, 3, k); int idx = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, 3, k + 1); const char* str = lua_tostring(L, -1); fl->add_mark(idx, str); lua_pop(L, 1); if (!str) break; } AGG_LOCK(); hol->add(fl); if (create_hol) p->set_xaxis_hol(hol); AGG_UNLOCK(); plot_update_raw (L, p, 1); return 0; }
static int luazmq_skt_set_str_arr (lua_State *L, int option_name) { zsocket *skt; size_t len, tlen, i; const char *option_value; int ret; if(!lua_istable(L, 2)) return luazmq_skt_set_str(L, option_name); skt = luazmq_getsocket(L); tlen = lua_objlen(L,2); for (i = 1; i <= tlen; i++){ lua_rawgeti(L, 2, i); option_value = luaL_checklstring(L, -1, &len); ret = zmq_setsockopt(skt->skt, option_name, option_value, len); if (ret == -1){ int n = luazmq_fail(L, skt); lua_pushnumber(L, i); return n + 1; } } return luazmq_pass(L); }
LUALIB_API int luaL_ref(lua_State *L, int t) { int ref; t = abs_index(L, t); if (lua_isnil(L, -1)) { lua_pop(L, 1); /* remove from stack */ return LUA_REFNIL; /* `nil' has a unique fixed reference */ } lua_rawgeti(L, t, FREELIST_REF); /* get first free element */ ref = (int)lua_tointeger(L, -1); /* ref = t[FREELIST_REF] */ lua_pop(L, 1); /* remove it from stack */ if (ref != 0) { /* any free element? */ lua_rawgeti(L, t, ref); /* remove it from list */ lua_rawseti(L, t, FREELIST_REF); /* (t[FREELIST_REF] = t[ref]) */ } else { /* no free elements */ ref = (int)lua_objlen(L, t); ref++; /* create new reference */ } lua_rawseti(L, t, ref); return ref; }
intArrayType LuaScript::getGlobal_intArray(stringType name) { intArrayType value; lua_getglobal(L, name.c_str()); //find the length unsigned int length = lua_objlen(L, -1); //places all of the values into our floatarray for (int i = 1; i <= length; i++) { lua_rawgeti(L, -1, i); if (lua_isnumber(L, -1)) { value.push_back(lua_tointeger(L, -1)); } else { std::cerr << "LUA_ERROR: global integer array index at - " << i; std::cerr << " - cannot be converted to integer for value '" << name << "'"; std::cerr << std::endl; } lua_pop(L, 1); } lua_pop(L, 1); return value; }
size_t DLLConf::get_string(const char* __section, const char* __key, char* __buf, size_t __buflen) { if (__section != NULL) from_priv(__section, __key); else lua_getfield(m_lua, LUA_GLOBALSINDEX, __key); size_t length = lua_objlen(m_lua, -1); if (__buf != NULL) { if (lua_type(m_lua, -1) == LUA_TSTRING) memcpy(__buf, lua_tolstring(m_lua, -1, NULL), __buflen); else length = 0; } lua_settop(m_lua, -2); return length; }
/// wait for a group of processes. // @{process-wait.lua} shows a number of processes launched // in parallel // @param processes an array of @{Process} objects // @param all wait for all processes to finish (default false) // @param timeout wait upto this time in msec (default infinite) // @function wait_for_processes def wait_for_processes(Value processes, Boolean all, Int timeout = 0) { int status, i; Process *p; int n = lua_objlen(L,processes); HANDLE handles[MAXIMUM_WAIT_OBJECTS]; if (n > MAXIMUM_WAIT_OBJECTS) { return push_error_msg(L,"cannot wait on so many processes"); } for (i = 0; i < n; i++) { lua_rawgeti(L,processes,i+1); p = Process_arg(L,-1); handles[i] = p->hProcess; } status = WaitForMultipleObjects(n, handles, all, TIMEOUT(timeout)); status -= WAIT_OBJECT_0 + 1; if (status < 1 || status > n) { return push_error(L); } else { lua_pushinteger(L,status); return 1; } }
static double* jointL_setParameter( lua_State *L, int *n ) { int i; double *v; /* Check parameter. */ luaL_checktype(L, 2, LUA_TTABLE); if (lua_isnumber(L,3)) (*n) = lua_tonumber(L,3); else (*n) = (int)lua_objlen(L,2); /* Create and map vector. */ v = malloc( (size_t)(*n)*sizeof(double) ); for (i=0; i<*n; i++) { lua_pushnumber(L,i+1); lua_gettable(L,2); v[i] = lua_tonumber(L,-1); lua_pop(L,1); } return v; }
// Lua: sample( id, count ) static int adc_sample( lua_State *L ) { unsigned id, count, nchans = 1; int res, i; count = luaL_checkinteger( L, 2 ); if ( ( count == 0 ) || count & ( count - 1 ) ) return luaL_error( L, "count must be power of 2 and > 0" ); // If first parameter is a table, extract channel list if ( lua_istable( L, 1 ) == 1 ) { nchans = lua_objlen(L, 1); // Get/check list of channels and setup for( i = 0; i < nchans; i++ ) { lua_rawgeti( L, 1, i+1 ); id = luaL_checkinteger( L, -1 ); MOD_CHECK_ID( adc, id ); res = adc_setup_channel( id, intlog2( count ) ); if ( res != PLATFORM_OK ) return luaL_error( L, "sampling setup failed" ); } // Initiate sampling platform_adc_start_sequence(); } else if ( lua_isnumber( L, 1 ) == 1 ) { id = luaL_checkinteger( L, 1 ); MOD_CHECK_ID( adc, id ); res = adc_setup_channel( id, intlog2( count ) ); if ( res != PLATFORM_OK ) return luaL_error( L, "sampling setup failed" ); platform_adc_start_sequence(); } else { return luaL_error( L, "invalid channel selection" ); } return 0; }
/* does a deep copy of a table */ static int table_deepcopy_r(struct lua_State *L) { size_t s; /* 1: table to copy, 2: new table */ s = lua_objlen(L, -1); lua_createtable(L, 0, s); /* 3: iterator */ lua_pushnil(L); while(lua_next(L, -3)) { /* 4: value */ if(lua_istable(L, -1)) { table_deepcopy_r(L); /* 5: new table */ lua_pushvalue(L, -3); /* 6: key */ lua_pushvalue(L, -2); /* 7: value */ lua_settable(L, -6); /* pops 6 and 7 */ lua_pop(L, 1); /* pops 5 */ } else { lua_pushvalue(L, -2); /* 5: key */ lua_pushvalue(L, -2); /* 6: value */ lua_settable(L, -5); /* pops 5 and 6 */ } /* pops 4 */ lua_pop(L, 1); } /* transfer the meta table */ if(lua_getmetatable(L, -2)) lua_setmetatable(L, -2); return 1; }
static lua_State * get_new_thread(lua_State * L) { lua_pushlightuserdata(L , threadtableKey); lua_pushvalue(L,1); // duplicate script key, since we need to store later // stack is now [script key] [script key] lua_rawget(L, LUA_REGISTRYINDEX); // get the script table from the registry, on the top of the stack if (!lua_istable(L,-1)) { // if it doesn't exist create it lua_pop(L,1); lua_newtable(L); } // stack is now [script key] [table] lua_pushinteger(L, lua_objlen(L, -1) + 1); // push #table + 1 onto the stack lua_State * T = lua_newthread(L); // create new thread T // stack is now [script key] [table] [#table + 1] [thread] lua_rawset(L, -3); // store the new thread at #table +1 index of the table. // stack is now [script key] [table] lua_rawset(L, LUA_REGISTRYINDEX); // stack L is now empty return T; // now we can set up T's stack appropriately }
bool LuaAI::getTable(lua_State *L, QList<int> &table) { if (!lua_istable(L, -1)) { lua_pop(L, 1); return false; } #if (LUA_VERSION_NUM==501) size_t len = lua_objlen(L, -1); #else size_t len = lua_rawlen(L, -1); #endif size_t i; for (i = 0; i < len; i++) { lua_rawgeti(L, -1, i + 1); table << lua_tointeger(L, -1); lua_pop(L, 1); } lua_pop(L, 1); return true; }
static int l_gk_assign_lcores(lua_State *l) { uint32_t ctypeid; lua_Integer n; unsigned int *lcores, **ud; uint32_t correct_ctypeid = luaL_get_ctypeid(l, CTYPE_STRUCT_GK_CONFIG_PTR); /* First argument must be of type CTYPE_STRUCT_GK_CONFIG_PTR. */ luaL_checkcdata(l, 1, &ctypeid, CTYPE_STRUCT_GK_CONFIG_PTR); if (ctypeid != correct_ctypeid) luaL_error(l, "Expected `%s' as first argument", CTYPE_STRUCT_GK_CONFIG_PTR); /* Second argument must be a table. */ luaL_checktype(l, 2, LUA_TTABLE); n = lua_objlen(l, 2); /* Get size of the table. */ if (n <= 0) return 0; /* No results. */ ud = lua_newuserdata(l, sizeof(lcores)); lua_pushcfunction(l, protected_gk_assign_lcores); lua_insert(l, 1); lcores = rte_malloc("gk_conf.lcores", n * sizeof(*lcores), 0); if (lcores == NULL) luaL_error(l, "DPDK has run out memory"); *ud = lcores; /* lua_pcall() is used here to avoid leaking @lcores. */ if (lua_pcall(l, 3, 0, 0)) { rte_free(lcores); lua_error(l); } return 0; }
int w_Mesh_setVertices(lua_State *L) { Mesh *t = luax_checkmesh(L, 1); size_t vertex_count = lua_objlen(L, 2); std::vector<Vertex> vertices; vertices.reserve(vertex_count); // Get the vertices from the table. for (size_t i = 1; i <= vertex_count; i++) { lua_rawgeti(L, 2, i); if (lua_type(L, -1) != LUA_TTABLE) return luax_typerror(L, 2, "table of tables"); for (int j = 1; j <= 8; j++) lua_rawgeti(L, -j, j); Vertex v; v.x = (float) luaL_checknumber(L, -8); v.y = (float) luaL_checknumber(L, -7); v.s = (float) luaL_optnumber(L, -6, 0.0); v.t = (float) luaL_optnumber(L, -5, 0.0); v.r = (unsigned char) luaL_optinteger(L, -4, 255); v.g = (unsigned char) luaL_optinteger(L, -3, 255); v.b = (unsigned char) luaL_optinteger(L, -2, 255); v.a = (unsigned char) luaL_optinteger(L, -1, 255); lua_pop(L, 9); vertices.push_back(v); } luax_catchexcept(L, [&](){ t->setVertices(vertices); }); return 0; }
// Lua -> JSON static int _encode(lua_State *L) { //app_t *app = lua_touserdata(L, lua_upvalueindex(1)); if(lua_istable(L, 1) && !lua_objlen(L, 1)) { cJSON *root = _encode_object(L, 1); char *json = cJSON_PrintUnformatted(root); lua_pushnil(L); // no error lua_pushstring(L, json); free(json); cJSON_Delete(root); } else { lua_pushstring(L, "not an object table"); lua_pushnil(L); } return 2; }
QVariant GetValueFromLuaState(lua_State *L, const char *table_name, const char *key){ lua_getglobal(L, table_name); lua_getfield(L, -1, key); QVariant data; switch(lua_type(L, -1)){ case LUA_TSTRING: { data = QString::fromUtf8(lua_tostring(L, -1)); lua_pop(L, 1); break; } case LUA_TNUMBER:{ data = lua_tonumber(L, -1); lua_pop(L, 1); break; } case LUA_TTABLE:{ QStringList list; size_t size = lua_objlen(L, -1); for(size_t i=0; i<size; i++){ lua_rawgeti(L, -1, i+1); QString element = QString::fromUtf8(lua_tostring(L, -1)); lua_pop(L, 1); list << element; } data = list; } default: break; } lua_pop(L, 1); return data; }
/* xmlreader.from_string(str [, base_url] [, encoding] [,options]) */ static int xmlreader_from_string(lua_State *L) { const char *str = luaL_checkstring(L, 1); const char *url = luaL_optstring(L, 2, NULL); const char *enc = luaL_optstring(L, 3, NULL); int opt = 0; if (lua_gettop(L) > 3) { lua_pop(L, lua_gettop(L) - 4); luaL_checktype(L, 4, LUA_TTABLE); opt = get_parser_option(L); } xmlreader xr = push_xmlreader(L, _xmlreader_from_string(str, lua_objlen(L, 1), url, enc, opt)); if (xr == NULL) lua_pushnil(L); /* else xmlTextReaderSetStructuredErrorHandler(xr, xmlreader_error_handler, L); */ return 1; }
int GetTableSize(lua_State *L, int tableIndex) { // Expensive call, but it's the only way to get the size of a table which uses // non-integers for keys int tableCount = lua_objlen(L, tableIndex); if (tableCount != 0) return tableCount; // Push the first key to get lua_pushnil(L); while (lua_next(L, tableIndex)) { tableCount++; // pop off the value, but leave the key for the next call to lua_next() lua_pop(L, 1); } return tableCount; }
void QueueEvent(const char *eventName, Object *o1) { LUA_DEBUG_START(L) s_eventsPending = true; lua_getglobal(L, "__pendingEvents"); size_t len = lua_objlen (L, -1); lua_pushinteger(L, len+1); // create event: { type=>eventName, 1=>o1,2=>o2 } lua_createtable (L, 2, 1); lua_pushstring(L, eventName); lua_setfield(L, -2, "type"); lua_pushinteger(L, 1); OOLUA::push2lua(L, o1); lua_settable(L, -3); // insert event into __pendingEvents lua_settable(L, -3); lua_pop(L, 1); LUA_DEBUG_END(L, 0) }
// g_read() static int file_g_read( lua_State* L, int n, int16_t end_char ) { if(n< 0 || n>LUAL_BUFFERSIZE) n = LUAL_BUFFERSIZE; if(end_char < 0 || end_char >255) end_char = EOF; int ec = (int)end_char; luaL_Buffer b; if((FS_OPEN_OK - 1)==file_fd) return luaL_error(L, "open a file first"); luaL_buffinit(L, &b); char *p = luaL_prepbuffer(&b); int c = EOF; int i = 0; do{ c = fs_getc(file_fd); if(c==EOF){ break; } p[i++] = (char)(0xFF & c); }while((c!=EOF) && (c!=ec) && (i<n) ); #if 0 if(i>0 && p[i-1] == '\n') i--; /* do not include `eol' */ #endif if(i==0){ luaL_pushresult(&b); /* close buffer */ return (lua_objlen(L, -1) > 0); /* check whether read something */ } luaL_addsize(&b, i); luaL_pushresult(&b); /* close buffer */ return 1; /* read at least an `eol' */ }
// __len metamethod handler static int l_str_len(lua_State *L) { luaL_checktype(L, 1, LUA_TUSERDATA); // Fetch proxied value aux_push_weak_table(L, 0); lua_pushvalue(L, 1); lua_gettable(L, -2); // String tables are proxied in Lua, and Lua tables do not honour __len // so use ipairs to get the unproxied table to call __len on. if(lua_type(L, -1) == LUA_TTABLE) { lua_getglobal(L, "ipairs"); lua_insert(L, -2); lua_call(L, 1, 2); lua_replace(L, -2); } lua_pushinteger(L, (lua_Integer)lua_objlen(L, -1)); return 1; }
bool luaval_to_std_vector_ushort(lua_State* L, int lo, std::vector<unsigned short>* ret, const char* funcName) { if (NULL == L || NULL == ret || lua_gettop(L) < lo) return false; tolua_Error tolua_err; bool ok = true; if (!tolua_istable(L, lo, 0, &tolua_err)) { #if COCOS2D_DEBUG >=1 luaval_to_native_err(L,"#ferror:",&tolua_err,funcName); #endif ok = false; } if (ok) { size_t len = lua_objlen(L, lo); for (size_t i = 0; i < len; i++) { lua_pushnumber(L, i + 1); lua_gettable(L,lo); if(lua_isnumber(L, -1)) { ret->push_back((unsigned short)tolua_tonumber(L, -1, 0)); } else { // CCASSERT(false, "unsigned short type is needed"); } lua_pop(L, 1); } } return ok; }
static int snapshot(lua_State* L) { lua_State *dL = luaL_newstate(); int len; const void * p; lua_newtable(dL); #if LUA_VERSION_NUM == 503 lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS); #else lua_pushvalue(L, LUA_GLOBALSINDEX); #endif mark_root_table(L, dL, RT_GLOBAL); lua_pop(L, 1); lua_pushvalue(L, LUA_REGISTRYINDEX); p = lua_topointer(L, -1); len = mark_root_table(L, dL, RT_REGISTRY); lua_pop(L, 1); make_report(L, dL); lua_newtable(L); lua_pushstring(L, "[REGISTRY Level 1]"); lua_setfield(L, -2, "name"); lua_pushnumber(L, RT_REGISTRY); lua_setfield(L, -2, "type"); lua_pushnumber(L, len); lua_setfield(L, -2, "size"); lua_pushfstring(L, "%p", p); lua_setfield(L, -2, "pointer"); lua_pushstring(L, ""); lua_setfield(L, -2, "used_in"); lua_rawseti(L, -2, lua_objlen(L, -2) + 1); lua_close(dL); return 1; }
bool lua_details::list_table(lua_State* L, int idx, TableInfo& out, int recursive) { out.clear(); if (lua_type(L, idx) != LUA_TTABLE) return false; int size= lua_objlen(L, idx); out.reserve(size); // table to traverse lua_pushvalue(L, idx); // push a key lua_pushnil(L); pop_stack_elements pop(L, 2); // remove key & table off the stack at the end of this fn // pop_stack_elements pop(L, 1); // remove table off the stack at the end of this fn int table= lua_gettop(L) - 1; // traverse a table while (lua_next(L, table)) { pop_stack_elements pop(L, 1); LuaField field; capture_value(L, field.key, -2); capture_value(L, field.val, -1, recursive); out.push_back(field); } pop.dec(); // final lua_next call removed key return true; }
static void readVertex(lua_State* state, graphics_Vertex* out, bool *hasVertexColor) { if(!lua_istable(state, -1) || lua_objlen(state, -1) < 4) { lua_pushstring(state, "Table entry is not a vertex"); lua_error(state); // does not return return; // hint the compiler } _Static_assert(sizeof(graphics_Vertex) == 8*sizeof(float), ""); float *t = (float*)out; for(int i = 0; i < 4; ++i) { lua_rawgeti(state, -1, i+1); t[i] = l_tools_toNumberOrError(state, -1); lua_pop(state, 1); } for(int i = 4; i < 8; ++i) { lua_rawgeti(state, -1, i+1); t[i] = luaL_optnumber(state, -1, 255.0f) / 255.0f; *hasVertexColor = (*hasVertexColor) || t[i] != 1.0f; lua_pop(state, 1); } }