const char* lua_getupvalue(lua_State *L, int funcIndex, int n) { const Value* func = GetValueForIndex(L, funcIndex); luai_apicheck(L, Value_GetIsClosure(func) ); Closure* closure = func->closure; if (closure->c) { if (n >= 1 && n <= closure->cclosure.numUpValues) { PushValue(L, &closure->cclosure.upValue[n - 1]); // Up values to a C function are unnamed. return ""; } } else { if (n >= 1 && n <= closure->lclosure.numUpValues) { PushValue(L, closure->lclosure.upValue[n - 1]->value); // Get the name of the up value from the prototype. String* name = closure->lclosure.prototype->upValue[n - 1]; return String_GetData(name); } } return NULL; }
LUA_API int lua_getinfo(lua_State* L, const char* what, lua_Debug* ar) { int status; Closure* f = NULL; CallInfo* ci = NULL; lua_lock(L); if (*what == '>') { StkId func = L->top - 1; luai_apicheck(L, ttisfunction(func)); what++; /* skip the '>' */ f = clvalue(func); L->top--; /* pop function */ } else if (ar->i_ci != 0) /* no tail call? */ { ci = L->base_ci + ar->i_ci; lua_assert(ttisfunction(ci->func)); f = clvalue(ci->func); } status = auxgetinfo(L, what, ar, f, ci); if (strchr(what, 'f')) { if (f == NULL) setnilvalue(L->top); else setclvalue(L, L->top, f); incr_top(L); } if (strchr(what, 'L')) collectvalidlines(L, f); lua_unlock(L); return status; }
/** * Accepts negative and pseudo indices. */ static Value* GetValueForIndex(lua_State* L, int index) { Value* result = NULL; if (index > 0) { // Absolute stack index. result = L->stackBase + (index - 1); if (result >= L->stackTop) { return &L->dummyObject; } } else if (index > LUA_REGISTRYINDEX) { // Stack index relative to the top of the stack. luai_apicheck(L, index != 0 && -index <= L->stackTop - L->stackBase); result = L->stackTop + index; } else if (index == LUA_GLOBALSINDEX) { // Global. result = &L->globals; } else if (index == LUA_REGISTRYINDEX) { // Registry. result = &L->registry; } else if (index == LUA_ENVIRONINDEX) { CallFrame* frame = State_GetCallFrame(L); if (frame->function == NULL) { Vm_Error(L, "no calling environment"); } // Temporarily store the environment table in the state since we need // to return a pointer to a Value. result = &L->env; SetValue(result, frame->function->closure->env); } else { // C up value. CallFrame* frame = State_GetCallFrame(L); Closure* closure = frame->function->closure; index = LUA_GLOBALSINDEX - index; if (index <= closure->cclosure.numUpValues) { return &closure->cclosure.upValue[index - 1]; } return &L->dummyObject; } ASSERT(result != NULL); return result; }
void lua_rawseti(lua_State* L, int index, int n) { Value* table = GetValueForIndex(L, index); luai_apicheck(L, Value_GetIsTable(table) ); Value* value = GetValueForIndex(L, -1); Table_SetTable(L, table->table, n, value); Pop(L, 1); }
int lua_setmetatable(lua_State* L, int index) { luai_apicheck(L, GetStackSize(L) >= 1); Value* object = GetValueForIndex(L, index); Value* metatable = GetValueForIndex(L, -1); Table* table = NULL; if (!Value_GetIsNil(metatable)) { luai_apicheck(L, Value_GetIsTable(metatable) ); table = metatable->table; } Value_SetMetatable( L, object, table ); Pop(L, 1); return 1; }
int lua_setfenv(lua_State *L, int index) { Value* object = GetValueForIndex(L, index); Value* env = GetValueForIndex(L, -1); luai_apicheck(L, Value_GetIsTable(env) ); int result = Value_SetEnv(L, object, env->table); Pop(L, 1); return result; }
void lua_rawgeti(lua_State *L, int index, int n) { Value* table = GetValueForIndex(L, index); luai_apicheck(L, Value_GetIsTable(table) ); const Value* value = Table_GetTable(L, table->table, n); if (value == NULL) { PushNil(L); } else { PushValue(L, value); } }
int lua_next(lua_State* L, int index) { Value* table = GetValueForIndex(L, index); luai_apicheck(L, Value_GetIsTable(table) ); Value* key = GetValueForIndex(L, -1); const Value* value = Table_Next(table->table, key); if (value == NULL) { Pop(L, 1); return 0; } PushValue(L, value); return 1; }
void lua_settop(lua_State *L, int index) { if (index < 0) { L->stackTop += index + 1; luai_apicheck(L, L->stackTop >= L->stackBase ); } else { Value* value = L->stackTop; Value* top = L->stackBase + index; while (value < top) { SetNil(value); ++value; } L->stackTop = top; } }
void lua_rawget(lua_State* L, int index) { Value* table = GetValueForIndex( L, index ); luai_apicheck(L, Value_GetIsTable(table) ); const Value* key = GetValueForIndex(L, -1); const Value* value = Table_GetTable(L, table->table, key); if (value != NULL) { *(L->stackTop - 1) = *value; } else { SetNil(L->stackTop - 1); } }
LUA_API int ICACHE_FLASH_ATTR lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { int status; Closure *f = NULL; CallInfo *ci = NULL; void *plight = NULL; lua_lock(L); if (*what == '>') { StkId func = L->top - 1; luai_apicheck(L, ttisfunction(func) || ttislightfunction(func)); what++; /* skip the '>' */ if (ttisfunction(func)) f = clvalue(func); else plight = fvalue(func); L->top--; /* pop function */ } else if (ar->i_ci != 0) { /* no tail call? */ ci = L->base_ci + ar->i_ci; lua_assert(ttisfunction(ci->func) || ttislightfunction(ci->func)); if (ttisfunction(ci->func)) f = clvalue(ci->func); else plight = fvalue(ci->func); } status = auxgetinfo(L, what, ar, f, plight, ci); if (c_strchr(what, 'f')) { if (f != NULL) setclvalue(L, L->top, f) else if (plight != NULL) setfvalue(L->top, plight) else setnilvalue(L->top); incr_top(L); } if (c_strchr(what, 'L')) collectvalidlines(L, f); lua_unlock(L); return status; }
void lua_replace(lua_State *L, int index) { if (index == LUA_ENVIRONINDEX) { // Special case for the environment index since we can only assign table // values, and the value returned by GetValueForIndex is a copy. CallFrame* frame = State_GetCallFrame(L); if (frame->function == NULL) { Vm_Error(L, "no calling environment"); } const Value* src = L->stackTop - 1; luai_apicheck(L, Value_GetIsTable(src)); frame->function->closure->env = src->table; --L->stackTop; } else { Value* dst = GetValueForIndex(L, index); --L->stackTop; *dst = *L->stackTop; } }
int lua_getinfo(lua_State* L, const char* what, lua_Debug* ar) { const Closure* function = NULL; const CallFrame* frame = NULL; if (what[0] == '>') { const Value* value = L->stackTop - 1; luai_apicheck(L, Value_GetIsClosure(value) ); function = value->closure; ++what; } else { luai_apicheck(L, ar->activeFunction <= Vm_GetCallStackSize(L) ); frame = L->callStackBase + ar->activeFunction; if (frame->function != NULL) { ASSERT( Value_GetIsClosure(frame->function) ); function = frame->function->closure; } } int result = 1; while (what[0] != 0) { switch (what[0]) { case 'n': ar->name = NULL; ar->namewhat = ""; break; case 'S': ar->source = NULL; ar->short_src[0] = 0; ar->linedefined = -1; ar->lastlinedefined = -1; if (function == NULL) { ar->what = "main"; ar->source = NULL; } else if (function->c) { ar->what = "C"; ar->source = "=[C]";; } else { ar->what = "Lua"; ar->source = String_GetData(function->lclosure.prototype->source); Prototype_GetName(function->lclosure.prototype, ar->short_src, LUA_IDSIZE); } break; case 'l': if (function == NULL || function->c) { ar->currentline = -1; } else { size_t ip = frame->ip - function->lclosure.prototype->code; ar->currentline = function->lclosure.prototype->sourceLine[ip]; } break; case 'u': if (function != NULL) { ar->nups = 0; } else if (function->c) { ar->nups = function->cclosure.numUpValues; } else { ar->nups = function->lclosure.numUpValues; } break; case 'f': // Pushes onto the stack the function that is running at the given level PushValue(L, frame->function); break; case 'L': // pushes onto the stack a table whose indices are the numbers of the lines that // are valid on the function. (A valid line is a line with some associated code, // that is, a line where you can put a break point. Non-valid lines include empty // lines and comments ASSERT(0); break; default: result = 0; } ++what; } return result; }