Skip to content

Commit

Permalink
CALL instruction now uses function metadata to determine target addre…
Browse files Browse the repository at this point in the history
…ss and number of arguments
  • Loading branch information
parrt committed Apr 15, 2015
1 parent 2db2c0a commit bb6674f
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/vm/Bytecode.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public Instruction(String name, int nargs) {
new Instruction("gstore", 1),
new Instruction("print"),
new Instruction("pop"),
new Instruction("call", 2), // call addr, nargs
new Instruction("call", 1), // call index of function in meta-info table
new Instruction("ret"),
new Instruction("halt")
};
Expand Down
15 changes: 15 additions & 0 deletions src/vm/FuncMetaData.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package vm;

public class FuncMetaData {
public String name;
public int nargs;
public int nlocals;
public int address; // bytecode address

public FuncMetaData(String name, int nargs, int nlocals, int address) {
this.name = name;
this.nargs = nargs;
this.nlocals = nlocals;
this.address = address;
}
}
27 changes: 17 additions & 10 deletions src/vm/Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ public class Test {
HALT // 24
};

static int fact = 0;
static int FACTORIAL_INDEX = 0;
static int FACTORIAL_ADDRESS = 0;
static int MAIN_ADDRESS = 21;
static int[] factorial = {
//.def fact: ARGS=1, LOCALS=0 ADDRESS
//.def factorial: ARGS=1, LOCALS=0 ADDRESS
// IF N < 2 RETURN 1
LOAD, 0, // 0
ICONST, 2, // 2
Expand All @@ -73,19 +75,24 @@ public class Test {
LOAD, 0, // 12
ICONST, 1, // 14
ISUB, // 16
CALL, fact, 1, // 17
IMUL, // 20
RET, // 21
CALL, FACTORIAL_INDEX, // 17
IMUL, // 19
RET, // 20
//.DEF MAIN: ARGS=0, LOCALS=0
// PRINT FACT(1)
ICONST, 5, // 22 <-- MAIN METHOD!
CALL, fact, 1, // 24
PRINT, // 27
HALT // 28
ICONST, 5, // 21 <-- MAIN METHOD!
CALL, FACTORIAL_INDEX, // 23
PRINT, // 25
HALT // 26
};

static FuncMetaData[] metadata = {
//.def factorial: ARGS=1, LOCALS=0 ADDRESS
new FuncMetaData("factorial", 1, 0, FACTORIAL_ADDRESS)
};

public static void main(String[] args) {
VM vm = new VM(factorial, 22, 0);
VM vm = new VM(factorial, MAIN_ADDRESS, 0, metadata);
vm.trace = true;
vm.exec();
}
Expand Down
19 changes: 15 additions & 4 deletions src/vm/VM.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,25 @@ public class VM {
int[] stack; // Operand stack, grows upwards
Context[] callstack;// call stack, grows upwards

/** Metadata about the functions allows us to refer to functions by
* their index in this table. It makes code generation easier for
* the bytecode compiler because it doesn't have to resolve
* addresses for forward references. It can generate simply
* "CALL i" where i is the index of the function. Later, the
* compiler can store the function address in the metadata table
* when the code is generated for that function.
*/
FuncMetaData[] metadata;

public boolean trace = false;

public VM(int[] code, int startip, int nglobals) {
public VM(int[] code, int startip, 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() {
Expand Down Expand Up @@ -127,15 +138,15 @@ protected void cpu() {
break;
case CALL :
// expects all args on stack
addr = code[ip++]; // target addr of function
int nargs = code[ip++]; // how many args got pushed
int findex = code[ip++]; // index of target function
int nargs = metadata[findex].nargs; // how many args got pushed
callstack[++callsp] = new Context(ip,nargs);
// copy args into new context
for (int i=0; i<nargs; i++) {
callstack[callsp].locals[i] = stack[sp-i];
}
sp -= nargs;
ip = addr; // jump to function
ip = metadata[findex].address; // jump to function
// TODO: code preamble of func must push space for locals
break;
case RET:
Expand Down

0 comments on commit bb6674f

Please sign in to comment.