diff --git a/src/vm/Context.java b/src/vm/Context.java index 4bae0eb..68086ce 100644 --- a/src/vm/Context.java +++ b/src/vm/Context.java @@ -2,11 +2,15 @@ /** To call, push one of these and pop to return */ public class Context { + Context invokingContext; // parent in the stack or "caller" + FuncMetaData metadata; // info about function we're executing int returnip; int[] locals; // args + locals, indexed from 0 - public Context(int returnip, int nlocals) { + public Context(Context invokingContext, int returnip, FuncMetaData metadata) { + this.invokingContext = invokingContext; this.returnip = returnip; - locals = new int[nlocals]; + this.metadata = metadata; + locals = new int[metadata.nargs+metadata.nlocals]; } } diff --git a/src/vm/Test.java b/src/vm/Test.java index 4cc9c7f..89c176b 100644 --- a/src/vm/Test.java +++ b/src/vm/Test.java @@ -57,8 +57,11 @@ public class Test { // PRINT "LOOPED "+N+" TIMES." HALT // 24 }; + static FuncMetaData[] loop_metadata = { + new FuncMetaData("main", 0, 0, 0) + }; - static int FACTORIAL_INDEX = 0; + static int FACTORIAL_INDEX = 1; static int FACTORIAL_ADDRESS = 0; static int MAIN_ADDRESS = 21; static int[] factorial = { @@ -88,15 +91,15 @@ public class Test { }; static FuncMetaData[] factorial_metadata = { //.def factorial: ARGS=1, LOCALS=0 ADDRESS + new FuncMetaData("main", 0, 0, MAIN_ADDRESS), new FuncMetaData("factorial", 1, 0, FACTORIAL_ADDRESS) }; - static int[] f = { // ADDRESS //.def main() { print f(10); } ICONST, 10, // 0 - CALL, 0, // 2 + CALL, 1, // 2 PRINT, // 4 HALT, // 5 //.def f(x): ARGS=1, LOCALS=1 @@ -110,22 +113,21 @@ public class Test { RET }; static FuncMetaData[] f_metadata = { - //.def factorial: ARGS=1, LOCALS=0 ADDRESS + new FuncMetaData("main", 0, 0, 0), new FuncMetaData("f", 1, 1, 6) }; public static void main(String[] args) { - VM vm = new VM(factorial, MAIN_ADDRESS, 0, factorial_metadata); - vm.trace = true; - vm.exec(); + VM vm = new VM(factorial, 0, factorial_metadata); + vm.trace = false; + vm.exec(factorial_metadata[0].address); - vm = new VM(f, 0, 2, f_metadata); - vm.trace = true; - vm.exec(); + vm = new VM(f, 2, f_metadata); + vm.exec(f_metadata[0].address); + vm.dumpDataMemory(); - vm = new VM(loop, 0, 2, null); - vm.trace = true; - vm.exec(); + vm = new VM(loop, 2, loop_metadata); + vm.exec(loop_metadata[0].address); } } diff --git a/src/vm/VM.java b/src/vm/VM.java index 008204c..6c3e063 100644 --- a/src/vm/VM.java +++ b/src/vm/VM.java @@ -32,15 +32,12 @@ public class VM { // registers int ip; // instruction pointer register int sp = -1; // stack pointer register - int callsp = -1; // call stack pointer register - - int startip = 0; // where execution begins // memory int[] code; // word-addressable code memory but still bytecodes. int[] globals; // global variable space int[] stack; // Operand stack, grows upwards - Context[] callstack;// call stack, grows upwards + Context ctx; // the active context /** Metadata about the functions allows us to refer to functions by * their index in this table. It makes code generation easier for @@ -54,17 +51,16 @@ public class VM { public boolean trace = false; - public VM(int[] code, int startip, int nglobals, FuncMetaData[] metadata) { + public VM(int[] code, int nglobals, FuncMetaData[] metadata) { this.code = code; - this.startip = startip; globals = new int[nglobals]; stack = new int[DEFAULT_STACK_SIZE]; - callstack = new Context[DEFAULT_CALL_STACK_SIZE]; this.metadata = metadata; } - public void exec() { + public void exec(int startip) { ip = startip; + ctx = new Context(null,0,metadata[0]); // simulate a call to main() cpu(); } @@ -124,7 +120,7 @@ protected void cpu() { break; case STORE : regnum = code[ip++]; - callstack[callsp].locals[regnum] = stack[sp--]; + ctx.locals[regnum] = stack[sp--]; break; case GSTORE : addr = code[ip++]; @@ -140,22 +136,22 @@ protected void cpu() { // expects all args on stack int findex = code[ip++]; // index of target function int nargs = metadata[findex].nargs; // how many args got pushed - int nlocals = metadata[findex].nlocals; - callstack[++callsp] = new Context(ip,nargs+nlocals); + ctx = new Context(ctx,ip,metadata[findex]); // copy args into new context for (int i=0; i stack = new ArrayList(); + Context c = ctx; + while ( c!=null ) { + if ( c.metadata!=null ) { + stack.add(0, c.metadata.name); + } + c = c.invokingContext; + } + return "calls="+stack.toString(); + } + protected String disInstr() { int opcode = code[ip]; String opName = Bytecode.instructions[opcode].name;