예제 #1
0
        static Arena ReadHeader(Script vm, int address)
        {
            var arena = new Arena();

            arena.length = vm.ReadWord(address - 1);
            arena.size   = vm.ReadWord(address - 2);
            arena.state  = (Arena.State)vm.ReadWord(address - 3);

            return(arena);
        }
예제 #2
0
        internal static Value Pop(Script vm)
        {
            var array   = new ArrayInfo(vm, vm.Argument(0).AsInt);
            int element = vm.Argument(1).AsInt;

            if (array.length <= 0)
            {
                vm.cpu.status = Cpu.Status.BAD_MEMORY_ACCESS;
                return(new Value(-1));
            }

            vm.WriteWord(array.length - 1, array.address - 1);
            return(new Value(vm.ReadWord(array.address + array.length - 1)));
        }
예제 #3
0
        public static string Disassemble(Script vm, int ip, out int size)
        {
            byte   opcode = vm.memory[ip];
            string name   = Script.instruction_table[opcode].GetMethodInfo().Name.ToLower();

            uint ip_u = (uint)ip;

            if (opcode < 0x17)
            {
                byte   op0   = vm.memory[ip + 1];
                byte   op1   = vm.memory[ip + 2];
                string dst_s = RegisterName(op0);
                string src_s = RegisterName(op1);
                size = LRX.SIZE;
                return(string.Format(
                           "0x{3:x8} {4:x2} {5:x2} {6:x2}           {0, -6}{1}, {2}",
                           name, dst_s, src_s, ip, opcode, op0, op1
                           ));
            }

            if (opcode < 0x24)
            {
                byte   op0 = vm.memory[ip + 1];
                string dst = RegisterName(op0);
                size = SRX.SIZE;
                return(string.Format(
                           "0x{2:x8} {3:x2} {4:x2}              {0, -6}{1}",
                           name, dst, ip, opcode, op0
                           ));
            }

            if (opcode < 0x34)
            {
                byte   op0 = vm.memory[ip + 1];
                string dst = RegisterName(op0);
                int    imm = vm.ReadWord((uint)ip + 2);
                byte   b0  = vm.ReadByte(ip_u + 2);
                byte   b1  = vm.ReadByte(ip_u + 3);
                byte   b2  = vm.ReadByte(ip_u + 4);
                byte   b3  = vm.ReadByte(ip_u + 5);
                size = IMRX.SIZE;
                return(string.Format(
                           "0x{3:x8} {4:x2} {9:x2} {5:x2} {6:x2} {7:x2} {8:x2}  {0, -6}{1}, {2:X}",
                           name, dst, imm, ip, opcode, b0, b1, b2, b3, op0
                           ));
            }

            if (opcode < 0x40)
            {
                int  imm = vm.ReadWord((uint)ip + 1);
                byte b0  = vm.ReadByte(ip_u + 1);
                byte b1  = vm.ReadByte(ip_u + 2);
                byte b2  = vm.ReadByte(ip_u + 3);
                byte b3  = vm.ReadByte(ip_u + 4);
                size = IMM.SIZE;
                return(string.Format(
                           "0x{2:x8} {3:x2} {4:x2} {5:x2} {6:x2} {7:x2}     {0, -6}{1:X}",
                           name, imm, ip, opcode, b0, b1, b2, b3
                           ));
            }

            size = 0;
            return("");
        }
예제 #4
0
        public bool Initialize(byte[] bytecode)
        {
            cpu = new Cpu()
            {
                registers = new int[Registers.NUM_REGISTERS],
                status    = new Cpu.Status(),
                // ip starts out pointing to the beginning of text section
                eip = Header.SIZE
            };

            // Stack pointer starts at the top of memory
            cpu.registers[Registers.ESP] = MAX_MEMORY;

            header = new Header()
            {
                sign_magic         = (short)(bytecode[0] | (bytecode[1] << 8)),
                sign_version       = (short)(bytecode[2] | (bytecode[3] << 8)),
                initial_stack_size = ReadWord(bytecode, 4),
                initial_heap_size  = ReadWord(bytecode, 8),
                import_table_ptr   = ReadWord(bytecode, 12),
                export_table_ptr   = ReadWord(bytecode, 16),
                text_ptr           = ReadWord(bytecode, 20),
                dat_ptr            = ReadWord(bytecode, 24)
            };

            // @Todo: verify signature
            int memory_size =
                (bytecode.Length >> 2)
                + header.initial_heap_size
                + header.initial_stack_size
                - (header.text_ptr >> 2);

            memory = new cell[memory_size];

            imports = new Dictionary <int, string>();
            locals  = new Dictionary <string, int>();

            // @Todo import table

            for (int i = header.import_table_ptr + 4; i < header.export_table_ptr;)
            {
                // Assuming UTF32 encoded string
                string name = Ava.String.FromBytes(bytecode, i);
                imports.Add(i >> 2, name);

                // String length in bytes + length value
                i += (name.Length * sizeof(cell)) + sizeof(cell);
            }

            for (int i = header.export_table_ptr + 4; i < header.text_ptr;)
            {
                // Assuming UTF32 encoded string
                string name = Ava.String.FromBytes(bytecode, i);
                i += (name.Length * sizeof(cell));

                int ptr = Script.ReadWord(bytecode, i);
                i += sizeof(int) * 2;

                locals.Add(name, ptr);
            }

            {
                int address = 0;
                for (int i = header.text_ptr; i < bytecode.Length; i += 4)
                {
                    memory[address] = Script.ReadWord(bytecode, i);
                    address++;
                }
            }

            cpu.registers = new cell[Registers.NUM_REGISTERS];

            // Stack currently empty, stk points to the lowest possible
            // address for the stack pointer, which is the end of the
            // data section.
            cpu.dat  = ((header.dat_ptr >> 2) - (header.text_ptr >> 2));
            cpu.heap = cpu.dat + 1;
            cpu.hp   = (cpu.heap + header.initial_heap_size);
            cpu.eip  = 0;
            cpu.registers[Registers.ESP] = MAX_MEMORY;
            return(true);
        }
예제 #5
0
        ///
        /// Create unpacked UTF32 string from byte array.
        /// start points to the first byte in the sequence
        /// and start-sizeof(int) points to the string length
        /// in cell sized characters.
        ///
        internal static string FromBytes(byte[] bytes, int start)
        {
            int length = Script.ReadWord(bytes, start - sizeof(int));

            return(Encoding.UTF32.GetString(bytes, start, length << 2));
        }
예제 #6
0
 internal ArrayInfo(Script vm, int array_ptr)
 {
     address  = array_ptr;
     capacity = vm.ReadWord(address - 2);
     length   = vm.ReadWord(address - 1);
 }