public static String readStringFromHeap(Stack data, Heap heap) { // get address int addr = data.popInt(); int ptr = data.readInt((int)data.Position + addr * sizeof(int)); return heap.readString(ptr); }
/// <summary> /// Executes a subroutine. All parameters must be written to the heap before execution. /// Afterwards the addresses of the parameters have to be stored in the stack (realtive to stackpointer). /// Mind this if you want to execute a script with external parameters. /// </summary> /// <param name="programCode">The script's code.</param> /// <param name="data">The data stack of the current script execution.</param> public void executeSub(MemoryStream programCode, int entryPoint, Stack data, Heap heap) { m_eip = entryPoint; m_ebp = (int)data.Position; // base pointer readNextOpCode(programCode); while (m_opcode != OpCode.HALT) { //eip = (int)programCode.Position; switch (m_opcode) { case OpCode.POP_INT: { break; } case OpCode.POP_FLOAT: { break; } case OpCode.POP_STRING: { break; } case OpCode.PUSH_INT: { data.push(readNextProgramInt(programCode)); break; } case OpCode.PUSH_FLOAT: { data.push(readNextProgramFloat(programCode)); break; } case OpCode.PUSH_STRING: { data.push(readNextProgramString(programCode)); break; } case OpCode.PUSH_ADDR: { int addr = readNextProgramInt(programCode); // address relative to ebp // read heap address from stack int heapAddr = data.readInt(m_ebp + addr); data.push(heapAddr); break; } case OpCode.PUSH_EBP: { data.push(m_ebp); break; } case OpCode.ADD_INT: { int val1 = data.popInt(); int val2 = data.popInt(); data.push(val1 + val2); break; } case OpCode.SUB_INT: { int val1 = data.popInt(); int val2 = data.popInt(); data.push(val1 - val2); break; } case OpCode.READ_INT: { int addr = data.popInt(); data.push(data.readInt(addr)); break; } case OpCode.WRITE_INT: { // read address int addr = data.popInt(); // read value int value = data.popInt(); // write data.writeInt(addr,value); break; } case OpCode.READ_FLOAT: { int addr = data.popInt(); data.push(data.readFlt(addr)); break; } case OpCode.WRITE_FLOAT: { // read address int addr = data.popInt(); // read value float value = data.popInt(); // write data.writeFlt(addr, value); break; } case OpCode.ALLOC_STRING_ON_HEAP: { String s = data.popString(); int address = heap.allocString(s); data.push(address); break; } case OpCode.READ_STRING_FROM_HEAP: { //int ptr = data.readInt((int)data.Position + addr * sizeof(int)); int ptr = data.popInt(); String s = heap.readString(ptr); data.push(s); break; } case OpCode.BEGIN_BLOCK: { // save base pointer m_ebp = (int)data.Position; data.push(m_ebp); break; } case OpCode.CALL_FUNCTION: { // get function address int func_addr = data.popInt(); // save instruction pointer data.push(m_eip); m_eip = func_addr; programCode.Position = m_eip; break; } case OpCode.RETURN: { m_eip = data.popInt(); // restore eip programCode.Position = m_eip; break; } case OpCode.END_BLOCK: { m_ebp = data.popInt(); // restore ebp data.set(m_ebp); break; } // Built in function case OpCode.NATIVE_CALL: { int f = readNextProgramInt(programCode); if (f > 0) { m_registeredFunctions.RegisteredFunctionAddresses[f].execute(data,heap); } else if (f < 0) { m_registeredFunctions.RegisteredFunctionAddresses[-1*f].end(data,heap); } break; } } readNextOpCode(programCode); } }