Example #1
0
static void Parse(lua_State* L, void* userData)
{

    // We currently can't run the GC while parsing because some objects used by
    // the parser are not properly stored in a root location.

    ParseArgs* args = static_cast<ParseArgs*>(userData);

    Input input;
    Input_Initialize(L, &input, args->reader, args->userdata);

    Prototype* prototype = NULL;

    if (Input_PeekByte(&input) == '\033')
    {
        // The data is a pre-compiled binary.
        prototype = LoadBinary(L, &input, args->name);
    }
    else
    {
        prototype = Parse(L, &input, args->name);
    }

    ASSERT(prototype != NULL);
    PushPrototype(L, prototype);

    Table* env = L->globals.table;
    Closure* closure = Closure_Create(L, prototype, env);
    PushClosure(L, closure);

    // Initialize the up values. Typically a top level check won't have any up
    // values, but if the chunk was created using string.dump or a similar method
    // it may. These up values will cease to function once the chunk is loaded.
    for (int i = 0; i < closure->lclosure.numUpValues; ++i)
    {
        closure->lclosure.upValue[i] = UpValue_Create(L);
    }

    // Remove the prototype from the stack.
    ASSERT( (L->stackTop - 2)->object == prototype );
    State_Remove(L, L->stackTop - 2);

}
Example #2
0
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;

}