summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/vm.c b/vm.c
index b5b66d3..6084f21 100644
--- a/vm.c
+++ b/vm.c
@@ -36,14 +36,19 @@ int runvm(State *S) {
#define RBYTE() (ch->bc.d[th->ip++])
#define RSHORT() (th->ip += 2, (uint16_t)( ch->bc.d[th->ip-2] | ch->bc.d[th->ip-1] << 8 ))
-#define PUSH(v) th->stack[th->sp++] = v;
-#define POP() (th->stack[--th->sp])
-#define PEEK() (th->stack[th->sp-1])
+#define PUSH(v) th->stack[th->fp + th->sp++] = v;
+#define POP() (th->stack[th->fp + --th->sp])
+#define PEEK() (th->stack[th->fp + th->sp-1])
while (1) {
ch = th->ch;
if (S->do_trace) {
- printf("%p ",(void *)ch);
+ printf("\t[%lu + %lu] : ",th->fp, th->sp);
+ for (int i = 0; i < th->sp; i++) {
+ print_val(th->stack[th->fp + i]);
+ printf(" ; ");
+ }
+ printf("\n%p ",(void *)ch);
disasm_instr(ch, th->ip);
}
uint8_t instr = RBYTE();
@@ -113,7 +118,7 @@ int runvm(State *S) {
case OP_GETLOCAL: {
uint8_t lidx = RBYTE();
- PUSH(th->stack[lidx]);
+ PUSH(th->stack[th->fp + lidx]);
break;
}
@@ -164,9 +169,9 @@ int runvm(State *S) {
case OP_CALL: {
uint8_t len = RBYTE();
- // ignore arguments for now
th->sp -= len-1;
Val callee = POP();
+
if (!IS_FUNC(callee)) {
fprintf(stderr, "can only call functions\n");
goto done;
@@ -176,9 +181,12 @@ int runvm(State *S) {
StackFrame *sf = &th->rstack[th->rsp++];
sf->ch = th->ch;
sf->ip = th->ip;
+ sf->fp = th->fp;
th->ch = &func->ch;
th->ip = 0;
+ th->fp = th->sp;
+ th->sp = len;
break;
}
@@ -192,8 +200,11 @@ int runvm(State *S) {
case OP_RET: {
StackFrame *sf = &th->rstack[--th->rsp];
+ size_t orig_fp = th->fp;
th->ch = sf->ch;
th->ip = sf->ip;
+ th->fp = sf->fp;
+ th->sp += (orig_fp - th->fp);
break;
}
case OP_HALT: