예제 #1
0
        private int DisassembleConstant(string name, GearsChunk chunk, int offset, EGearsOpCode constantType, Action <string> writeLine)
        {
            int constantIndex = (chunk.ReadCode(ref offset) << 8) + chunk.ReadCode(ref offset);

            switch (constantType)
            {
            case OP_LOAD_CONSTANT: {
                GearsValue value = chunk.ReadConstantValue(constantIndex);
                writeLine($"{name} const[{constantIndex}] ({value})");
            }
            break;

            case OP_LOAD_STRING: {
                string value = chunk.Strings.ReadStringConstant(constantIndex);
                writeLine($"{name} string[{constantIndex}] ({value})");
            }
            break;

            case OP_LOAD_FUNCTION: {
                string value = chunk.ReadConstantValueAsBitStr(constantIndex);
                writeLine($"{name} bitstr[{constantIndex}] ({value})");
            }
            break;
            }
            return(offset);
        }
예제 #2
0
        private int DisassembleTwoParams(string name, GearsChunk chunk, int offset, Action <string> writeLine)
        {
            int index = (chunk.ReadCode(ref offset) << 8) + chunk.ReadCode(ref offset);

            writeLine($"{name} ({index})");
            return(offset);
        }
예제 #3
0
        private int DisassembleInvoke(string name, GearsChunk chunk, int offset, Action <string> writeLine)
        {
            int    args      = chunk.ReadCode(ref offset);
            int    nameIndex = (chunk.ReadCode(ref offset) << 8) + chunk.ReadCode(ref offset);
            string value     = chunk.ReadConstantValueAsBitStr(nameIndex);

            writeLine($"{name} const[{nameIndex}] ({value})");
            return(offset);
        }
예제 #4
0
        private int DisassembleFunction(string name, GearsChunk chunk, int offset, Action <string> writeLine)
        {
            int argCount     = chunk.ReadCode(ref offset);
            int fnAddress    = (chunk.ReadCode(ref offset) << 8) + chunk.ReadCode(ref offset);
            int upvalueCount = chunk.ReadCode(ref offset);

            writeLine($"{name} ({argCount} arguments, {upvalueCount} upvalues) @{fnAddress:D4}");
            for (int i = 0; i < upvalueCount; i++)
            {
                chunk.ReadCode(ref offset); // local?
                chunk.ReadCode(ref offset); // index
            }
            return(offset);
        }
예제 #5
0
        private int Disassemble(GearsChunk chunk, int offset, Action <string> write, Action <string> writeLine)
        {
            write($"{chunk._Lines[offset]:D4}  {offset:D4}  ");
            EGearsOpCode instruction = (EGearsOpCode)chunk.ReadCode(ref offset);

            switch (instruction)
            {
            case OP_LOAD_CONSTANT:
                return(DisassembleConstant("OP_LOAD_CONSTANT", chunk, offset, OP_LOAD_CONSTANT, writeLine));

            case OP_LOAD_STRING:
                return(DisassembleConstant("OP_LOAD_STRING", chunk, offset, OP_LOAD_STRING, writeLine));

            case OP_LOAD_FUNCTION:
                return(DisassembleFunction("OP_LOAD_FUNCTION", chunk, offset, writeLine));

            case OP_NIL:
                return(DisassembleSimple("OP_NIL", chunk, offset, writeLine));

            case OP_TRUE:
                return(DisassembleSimple("OP_TRUE", chunk, offset, writeLine));

            case OP_FALSE:
                return(DisassembleSimple("OP_FALSE", chunk, offset, writeLine));

            case OP_POP:
                return(DisassembleSimple("OP_POP", chunk, offset, writeLine));

            case OP_GET_LOCAL:
                return(DisassembleTwoParams("OP_GET_LOCAL", chunk, offset, writeLine));

            case OP_SET_LOCAL:
                return(DisassembleTwoParams("OP_SET_LOCAL", chunk, offset, writeLine));

            case OP_DEFINE_GLOBAL:
                return(DisassembleConstant("OP_DEF_GLOBAL", chunk, offset, OP_LOAD_FUNCTION, writeLine));

            case OP_GET_GLOBAL:
                return(DisassembleConstant("OP_GET_GLOBAL", chunk, offset, OP_LOAD_FUNCTION, writeLine));

            case OP_SET_GLOBAL:
                return(DisassembleConstant("OP_SET_GLOBAL", chunk, offset, OP_LOAD_FUNCTION, writeLine));

            case OP_GET_UPVALUE:
                return(DisassembleTwoParams("OP_GET_UPVALUE", chunk, offset, writeLine));

            case OP_SET_UPVALUE:
                return(DisassembleTwoParams("OP_SET_UPVALUE", chunk, offset, writeLine));

            case OP_GET_PROPERTY:
                return(DisassembleConstant("OP_GET_PROPERTY", chunk, offset, OP_LOAD_FUNCTION, writeLine));

            case OP_SET_PROPERTY:
                return(DisassembleConstant("OP_SET_PROPERTY", chunk, offset, OP_LOAD_FUNCTION, writeLine));

            case OP_GET_SUPER:
                return(DisassembleConstant("OP_GET_SUPER", chunk, offset, OP_LOAD_FUNCTION, writeLine));

            case OP_EQUAL:
                return(DisassembleSimple("OP_EQUAL", chunk, offset, writeLine));

            case OP_GREATER:
                return(DisassembleSimple("OP_GREATER", chunk, offset, writeLine));

            case OP_LESS:
                return(DisassembleSimple("OP_LESS", chunk, offset, writeLine));

            case OP_ADD:
                return(DisassembleSimple("OP_ADD", chunk, offset, writeLine));

            case OP_SUBTRACT:
                return(DisassembleSimple("OP_SUBTRACT", chunk, offset, writeLine));

            case OP_MULTIPLY:
                return(DisassembleSimple("OP_MULTIPLY", chunk, offset, writeLine));

            case OP_DIVIDE:
                return(DisassembleSimple("OP_DIVIDE", chunk, offset, writeLine));

            case OP_NOT:
                return(DisassembleSimple("OP_NOT", chunk, offset, writeLine));

            case OP_NEGATE:
                return(DisassembleSimple("OP_NEGATE", chunk, offset, writeLine));

            case OP_JUMP:
                return(DisassembleTwoParams("OP_JUMP", chunk, offset, writeLine));

            case OP_JUMP_IF_FALSE:
                return(DisassembleTwoParams("OP_JUMP_IF_FALSE", chunk, offset, writeLine));

            case OP_LOOP:
                return(DisassembleTwoParams("OP_LOOP", chunk, offset, writeLine));

            case OP_CALL:
                return(DisassembleOneParam("OP_CALL", chunk, offset, writeLine));

            case OP_INVOKE:
                return(DisassembleInvoke("OP_INVOKE", chunk, offset, writeLine));

            case OP_SUPER_INVOKE:
                return(DisassembleInvoke("OP_SUPER_INVOKE", chunk, offset, writeLine));

            case OP_CLOSE_UPVALUE:
                return(DisassembleSimple("OP_CLOSE_UPVALUE", chunk, offset, writeLine));

            case OP_RETURN:
                return(DisassembleSimple("OP_RETURN", chunk, offset, writeLine));

            case OP_CLASS:
                return(DisassembleConstant("OP_CLASS", chunk, offset, OP_LOAD_FUNCTION, writeLine));

            case OP_INHERIT:
                return(DisassembleSimple("OP_INHERIT", chunk, offset, writeLine));

            case OP_METHOD:
                return(DisassembleSimple("OP_METHOD", chunk, offset, writeLine));

            default:
                writeLine($"Unknown opcode {instruction}");
                return(offset);
            }
        }