static Prototype* LoadBinary(lua_State* L, Input* input, const char* name) { Header header; size_t length = Input_ReadBlock(input, &header, sizeof(header)); if (length < sizeof(Header)) { return NULL; } // Check that the buffer is a compiled Lua chunk. if (header.magic[0] != '\033') { return NULL; } // Check for compatible platform if (header.endianness != 1 || header.intSize != sizeof(int) || header.sizetSize != sizeof(size_t) || header.numberSize != sizeof(lua_Number)) { return NULL; } char* data = Input_Read(input, &length); Prototype* prototype = Prototype_Create(L, data, length, name); Free(L, data, length); return prototype; }
Prototype* Function_CreatePrototype(lua_State* L, Function* function, String* source) { int convertedCodeSize = Prototype_GetConvertedCodeSize( function->code, function->codeSize ); Prototype* prototype = Prototype_Create( L, function->codeSize, convertedCodeSize, function->numConstants, function->numFunctions, function->numUpValues); PushPrototype(L, prototype); // Store the up values. memcpy(prototype->upValue, function->upValue, sizeof(String*) * function->numUpValues); // Store the code. memcpy(prototype->code, function->code, function->codeSize * sizeof(Instruction)); // Store the source information. prototype->source = source; Gc_IncrementReference(&L->gc, prototype, prototype->source); memcpy(prototype->sourceLine, function->sourceLine, function->codeSize * sizeof(int)); // Store the functions. for (int i = 0; i < function->numFunctions; ++i) { prototype->prototype[i] = Function_CreatePrototype(L, function->function[i], source); Gc_IncrementReference(&L->gc, prototype, prototype->prototype[i]); } // Store the constants. Value key; SetNil(&key); Table* constants = function->constants; const Value* value; while (value = Table_Next(L, constants, &key)) { int i; if (!Value_GetIsInteger(value, &i)) { ASSERT(0); } if (Value_GetIsTable(&key) && key.table == constants) { // The table itself is used to indicate nil values since nil values // cannot be saved in the table. SetNil(&prototype->constant[i]); } else { prototype->constant[i] = key; } Gc_IncrementReference(&L->gc, prototype, &prototype->constant[i]); } prototype->varArg = function->varArg; prototype->numParams = function->numParams; prototype->maxStackSize = function->maxStackSize; prototype->numUpValues = function->numUpValues; prototype->lineDefined = 0; prototype->lastLineDefined = 0; //PrintFunction(prototype); ASSERT( (L->stackTop - 1)->object == prototype ); Pop(L, 1); return prototype; }