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; }
static const char* FormatConstant(const Value* value, char buffer[64]) { if (Value_GetIsNumber(value)) { lua_number2str(buffer, value->number); } else if (Value_GetIsString(value)) { return String_GetData(value->string); } else if (Value_GetIsBoolean(value)) { strcpy(buffer, value->boolean ? "true" : "false"); } else if (Value_GetIsNil(value)) { strcpy(buffer, "nil"); } else { // Some other type of constant was stored that can't be saved into // the file. If this happens, it means we've introduced some new type // of constant but haven't handled it here. ASSERT(0); return "Unknown"; } return buffer; }
static void Output_WriteString(Output* output, const String* value) { // Length includes a null terminator. size_t length = value->length + 1; Output_Write( output, length ); Output_WriteBlock( output, String_GetData(value), length ); }
/** * Returns the name of the up value (for a Lua function) and upValue is set to * point to the address of where the up values value is stored. */ static const char* GetUpValue(Value* value, int n, Value** upValue) { if (!Value_GetIsClosure(value)) { return NULL; } Closure* closure = value->closure; if (closure->c) { if (n >= 1 && n <= closure->cclosure.numUpValues) { *upValue = &closure->cclosure.upValue[n - 1]; // Up values to a C function are unnamed. return ""; } } else { if (n >= 1 && n <= closure->lclosure.numUpValues) { *upValue = closure->lclosure.upValue[n - 1]->value; return String_GetData( closure->lclosure.prototype->upValue[n - 1] ); } } return NULL; }
const char* lua_tolstring(lua_State *L, int index, size_t* length ) { Value* value = GetValueForIndex(L, index); if (ToString(L, value)) { const String* string = value->string; if (length != NULL) { *length = string->length; } return String_GetData(string); } return NULL; }
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; }
const char* lua_typename(lua_State* L, int type) { return String_GetData( State_TypeName(L, type) ); }