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); }
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))); }
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(""); }
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); }
/// /// 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)); }
internal ArrayInfo(Script vm, int array_ptr) { address = array_ptr; capacity = vm.ReadWord(address - 2); length = vm.ReadWord(address - 1); }