Beispiel #1
0
void PrintFunction(const Proto *f, int full) {
    int i, n = f->sizep;
    PrintHeader(f);
    PrintCode(f);
    if (full) {
        PrintConstants(f);
        PrintLocals(f);
        PrintUpvalues(f);
    }
    for (i = 0; i < n; i++) PrintFunction(f->p[i], full);
}
Beispiel #2
0
void luaU_print(const Proto* f)
{
    int i,n=f->sizep;
    PrintHeader(f);
    PrintCode(f);
#ifdef DEBUG_PRINT
    PrintConstants(f);
    PrintLocals(f);
    PrintUpvalues(f);
#endif
    for (i=0; i<n; i++) luaU_print(f->p[i]);
}
Beispiel #3
0
void PrintFunction(Prototype* prototype)
{

    enum Format
    {
        Format_None,
        Format_A,
        Format_AB,
        Format_ABC,
        Format_ABx,
        Format_AsBx,
        Format_AC,
        Format_sBx,
    };

    static const Format format[] = 
        {
            Format_AB,      // Opcode_Move
            Format_ABx,     // Opcode_LoadK
            Format_ABC,     // Opcode_LoadBool
            Format_AB,      // Opcode_LoadNil
            Format_AB,      // Opcode_GetUpVal
            Format_ABx,     // Opcode_GetGlobal
            Format_ABC,     // Opcode_GetTable
            Format_ABx,     // Opcode_SetGlobal
            Format_AB,      // Opcode_SetUpVal
            Format_ABC,     // Opcode_SetTable
            Format_ABC,     // Opcode_NewTable
            Format_ABC,     // Opcode_Self
            Format_ABC,     // Opcode_Add 
            Format_ABC,     // Opcode_Sub
            Format_ABC,     // Opcode_Mul
            Format_ABC,     // Opcode_Div
            Format_ABC,     // Opcode_Mod
            Format_ABC,     // Opcode_Pow
            Format_AB,      // Opcode_Unm
            Format_AB,      // Opcode_Not
            Format_AB,      // Opcode_Len
            Format_ABC,     // Opcode_Concat
            Format_sBx,     // Opcode_Jmp
            Format_ABC,     // Opcode_Eq
            Format_ABC,     // Opcode_Lt
            Format_ABC,     // Opcode_Le
            Format_AC,      // Opcode_Test
            Format_ABC,     // Opcode_TestSet
            Format_ABC,     // Opcode_Call
            Format_ABC,     // Opcode_TailCall
            Format_AB,      // Opcode_Return
            Format_AsBx,    // Opcode_ForLoop
            Format_AsBx,    // Opcode_ForPrep
            Format_ABC,     // Opcode_TForLoop
            Format_ABC,     // Opcode_SetList
            Format_A,       // Opcode_Close
            Format_ABx,     // Opcode_Closure
            Format_AB,      // Opcode_VarArg
        };

    printf("; function\n");
    printf("; %d upvalues, %d params, %d stack slots\n",
        prototype->numUpValues, prototype->numParams, prototype->maxStackSize);

    PrintConstants(prototype);

    const int commentColumn = 30;
    const int argsColumn    = 20;

    int lineNumberDigits = 0;
    int log = prototype->codeSize;
    while (log > 0)
    {
        log /= 10;
        ++lineNumberDigits;
    }

    for (int i = 0; i < prototype->codeSize; ++i)
    {
        
        Instruction inst = prototype->code[i];
        
        Opcode opcode = LUA_GET_OPCODE(inst);
        int line = i + 1;

        const char* op = Opcode_GetAsText(opcode);
        int length = printf("[%0*d] %s",  lineNumberDigits, line, op);

        // Indent before printing the arguments.
        if (length < argsColumn)
        {
            length += printf("%*s", argsColumn - length, "");
        }

        switch (format[opcode])
        {
        case Format_A:
            length += printf("%d", LUA_GET_A(inst));
            break;
        case Format_AB:
            length += printf("%d %d", LUA_GET_A(inst), LUA_GET_B(inst));
            break;
        case Format_ABC:
            length += printf("%d %d %d", LUA_GET_A(inst), LUA_GET_B(inst), LUA_GET_C(inst));
            break;
        case Format_ABx:
            length += printf("%d %d", LUA_GET_A(inst), LUA_GET_Bx(inst));
            break;
        case Format_AsBx:
            length += printf("%d %d", LUA_GET_A(inst), LUA_GET_sBx(inst));
            break;
        case Format_AC:
            length += printf("%d %d", LUA_GET_A(inst), LUA_GET_C(inst));
            break;
        case Format_sBx:
            length += printf("%d", LUA_GET_sBx(inst));
            break;
        }

        // Indent before printing the comment.
        if (length < commentColumn)
        {
            length += printf("%*s", commentColumn - length, "");
        }

        char buffer1[64];
        char buffer2[64];

        const char* arg1 = NULL;
        const char* arg2 = NULL;

        switch (opcode)
        {
        case Opcode_GetGlobal:
            arg1 = FormatK(prototype, buffer1, LUA_GET_Bx(inst));
            printf("; r%d = _G[%s]", LUA_GET_A(inst), arg1); 
            break;
        case Opcode_Jmp:
            printf("; goto [%0*d]", lineNumberDigits, line + LUA_GET_sBx(inst) + 1); 
            break;
        case Opcode_Test:
            if (LUA_GET_C(inst))
            {
                printf("; if not r%d then goto [%0*d]", LUA_GET_A(inst), lineNumberDigits, line + 2);
            }
            else
            {
                printf("; if r%d then goto [%0*d]", LUA_GET_A(inst), lineNumberDigits, line + 2);
            }
            break;
        case Opcode_TestSet:
            if (LUA_GET_C(inst))
            {
                printf("; if r%d then r%d = r%d else goto [%0*d]", LUA_GET_B(inst), LUA_GET_A(inst), LUA_GET_B(inst), lineNumberDigits, line + 2);
            }
            else
            {
                printf("; if not r%d then r%d = r%d else goto [%0*d]", LUA_GET_B(inst), LUA_GET_A(inst), LUA_GET_B(inst), lineNumberDigits, line + 2);
            }
            break;
        case Opcode_Eq:
            arg1 = FormatRK( prototype, buffer1, LUA_GET_B(inst) );
            arg2 = FormatRK( prototype, buffer2, LUA_GET_C(inst) );
            if (LUA_GET_A(inst))
            {
                printf("; if %s ~= %s then goto [%0*d]", arg1, arg2,
                    lineNumberDigits, line + 2);
            }
            else
            {
                printf("; if %s == %s then goto [%0*d]", arg1, arg2,
                    lineNumberDigits, line + 2);
            }
            break;
        case Opcode_Lt:
            arg1 = FormatRK( prototype, buffer1, LUA_GET_B(inst) );
            arg2 = FormatRK( prototype, buffer2, LUA_GET_C(inst) );
            if (LUA_GET_A(inst))
            {
                printf("; if not (%s < %s) then goto [%0*d]", arg1, arg2,
                    lineNumberDigits, line + 2);
            }
            else
            {
                printf("; if %s < %s then goto [%0*d]", arg1, arg2,
                    lineNumberDigits, line + 2);
            }
            break;
        case Opcode_Le:
            arg1 = FormatRK( prototype, buffer1, LUA_GET_B(inst) );
            arg2 = FormatRK( prototype, buffer2, LUA_GET_C(inst) );
            if (LUA_GET_A(inst))
            {
                printf("; if not (%s <= %s) then goto [%0*d]", arg1, arg2,
                    lineNumberDigits, line + 2);
            }
            else
            {
                printf("; if %s <= %s then goto [%0*d]", arg1, arg2,
                    lineNumberDigits, line + 2);
            }
            break;
        case Opcode_LoadK:
            arg1 = FormatK( prototype, buffer1, LUA_GET_Bx(inst) );
            printf("; r%d = %s", LUA_GET_A(inst), arg1);
            break;
        case Opcode_LoadBool:
            if (LUA_GET_C(inst))
            {
                printf("; r%d = %s; goto [%0*d]", LUA_GET_A(inst), LUA_GET_B(inst) ? "true" : "false",
                    lineNumberDigits, line + 2);
            }
            else
            {
                printf("; r%d = %s", LUA_GET_A(inst), LUA_GET_B(inst) ? "true" : "false");
            }
            break;
        case Opcode_Call:
            {
                int numArgs    = LUA_GET_B(inst) - 1;
                int numResults = LUA_GET_C(inst) - 1;
                printf("; ");
                if (numArgs >= 0)
                {
                    printf("%d arguments", numArgs);
                }
                else
                {
                    printf("variable arguments");
                }
                if (numResults >= 0)
                {
                    printf(", %d results", numResults);
                }
                else
                {
                    printf(", variable results");
                }
            }
            break;
        }

        printf("\n");

    }

    printf("; end of function\n\n");

}