diff options
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-x | src/bytecode/vm.h | 61 |
1 files changed, 32 insertions, 29 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 23c3d89..f7852de 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -13,17 +13,20 @@ | |||
13 | 13 | ||
14 | typedef struct CallFrame { | 14 | typedef struct CallFrame { |
15 | // Current code being run. | 15 | // Current code being run. |
16 | Object procedure; | 16 | Chunk *chunk; |
17 | // Current program counter for this call. | 17 | // Current program counter for this call. |
18 | u8 *pc; | ||
19 | // Ref to stack. Is this really needed? | 18 | // Ref to stack. Is this really needed? |
20 | // Object *stack; | 19 | // Object *locals; |
20 | // Return counter. | ||
21 | u8 *rp; | ||
21 | } CallFrame; | 22 | } CallFrame; |
22 | 23 | ||
23 | typedef struct VM { | 24 | typedef struct VM { |
24 | CallFrame *frames; | 25 | CallFrame *frames; |
25 | // Stack. | 26 | // Stack. |
26 | Object *stack; | 27 | Object *stack; |
28 | // Program counter. | ||
29 | u8 *pc; | ||
27 | // Global variables. | 30 | // Global variables. |
28 | HashTable *globals; | 31 | HashTable *globals; |
29 | } VM; | 32 | } VM; |
@@ -37,9 +40,6 @@ void | |||
37 | vm_init(VM *vm) { | 40 | vm_init(VM *vm) { |
38 | *vm = (VM){0}; | 41 | *vm = (VM){0}; |
39 | array_init(vm->frames, VM_FRAMES_CAP); | 42 | array_init(vm->frames, VM_FRAMES_CAP); |
40 | for (size_t i = 0; i < array_cap(vm->frames); i++) { | ||
41 | vm->frames[i] = (CallFrame){0}; | ||
42 | } | ||
43 | array_init(vm->stack, VM_STACK_CAP); | 43 | array_init(vm->stack, VM_STACK_CAP); |
44 | vm->globals = ht_init(); | 44 | vm->globals = ht_init(); |
45 | } | 45 | } |
@@ -62,16 +62,16 @@ vm_reset(VM *vm) { | |||
62 | error_push((Error){ \ | 62 | error_push((Error){ \ |
63 | .type = ERR_TYPE_RUNTIME, \ | 63 | .type = ERR_TYPE_RUNTIME, \ |
64 | .value = ERR_WRONG_ARG_TYPE, \ | 64 | .value = ERR_WRONG_ARG_TYPE, \ |
65 | .line = chunk->lines[frame->pc - chunk->code - 1].line, \ | 65 | .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, \ |
66 | .col = chunk->lines[frame->pc - chunk->code - 1].col, \ | 66 | .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, \ |
67 | }) | 67 | }) |
68 | 68 | ||
69 | #define SYMBOL_NOT_FOUND_ERR() \ | 69 | #define SYMBOL_NOT_FOUND_ERR() \ |
70 | error_push((Error){ \ | 70 | error_push((Error){ \ |
71 | .type = ERR_TYPE_RUNTIME, \ | 71 | .type = ERR_TYPE_RUNTIME, \ |
72 | .value = ERR_SYMBOL_NOT_FOUND, \ | 72 | .value = ERR_SYMBOL_NOT_FOUND, \ |
73 | .line = chunk->lines[frame->pc - chunk->code - 1].line, \ | 73 | .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, \ |
74 | .col = chunk->lines[frame->pc - chunk->code - 1].col, \ | 74 | .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, \ |
75 | }) | 75 | }) |
76 | 76 | ||
77 | #define FIXNUM_ARITHMETIC_OP(OP) \ | 77 | #define FIXNUM_ARITHMETIC_OP(OP) \ |
@@ -137,9 +137,9 @@ vm_reset(VM *vm) { | |||
137 | void | 137 | void |
138 | vm_interpret(VM *vm) { | 138 | vm_interpret(VM *vm) { |
139 | CallFrame *frame = &vm->frames[array_size(vm->frames) - 1]; | 139 | CallFrame *frame = &vm->frames[array_size(vm->frames) - 1]; |
140 | Chunk *chunk = frame->procedure.chunk; | 140 | vm->pc = frame->chunk->code; |
141 | 141 | ||
142 | if (chunk->code == NULL || array_size(chunk->code) == 0) { | 142 | if (frame->chunk->code == NULL || array_size(frame->chunk->code) == 0) { |
143 | error_push((Error){ | 143 | error_push((Error){ |
144 | .type = ERR_TYPE_RUNTIME, | 144 | .type = ERR_TYPE_RUNTIME, |
145 | .value = ERR_EMPTY_CHUNK, | 145 | .value = ERR_EMPTY_CHUNK, |
@@ -147,8 +147,8 @@ vm_interpret(VM *vm) { | |||
147 | return; | 147 | return; |
148 | } | 148 | } |
149 | 149 | ||
150 | u8 *last = chunk->code + array_size(chunk->code); | 150 | u8 *last = frame->chunk->code + array_size(frame->chunk->code); |
151 | while (frame->pc < last) { | 151 | while (vm->pc < last) { |
152 | #ifdef DEBUG_TRACE_EXECUTION | 152 | #ifdef DEBUG_TRACE_EXECUTION |
153 | printf("stack: [ "); | 153 | printf("stack: [ "); |
154 | for (size_t i = 0; i < array_size(vm->stack); i++) { | 154 | for (size_t i = 0; i < array_size(vm->stack); i++) { |
@@ -158,13 +158,13 @@ vm_interpret(VM *vm) { | |||
158 | } | 158 | } |
159 | } | 159 | } |
160 | printf(" ]\nop: "); | 160 | printf(" ]\nop: "); |
161 | disassemble_instruction(chunk, (frame->pc - chunk->code)); | 161 | disassemble_instruction(frame->chunk, (vm->pc - frame->chunk->code)); |
162 | #endif | 162 | #endif |
163 | u8 instruction = *frame->pc++; | 163 | u8 instruction = *vm->pc++; |
164 | switch (instruction) { | 164 | switch (instruction) { |
165 | case OP_CONSTANT: { | 165 | case OP_CONSTANT: { |
166 | u8 constant = *frame->pc++; | 166 | u8 constant = *vm->pc++; |
167 | Object obj = chunk->constants[constant]; | 167 | Object obj = frame->chunk->constants[constant]; |
168 | array_push(vm->stack, obj); | 168 | array_push(vm->stack, obj); |
169 | } break; | 169 | } break; |
170 | case OP_DEF: { | 170 | case OP_DEF: { |
@@ -209,17 +209,17 @@ vm_interpret(VM *vm) { | |||
209 | case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break; | 209 | case OP_LESS_EQUAL: { FIXNUM_COMPARE_OP(<=); } break; |
210 | case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break; | 210 | case OP_GREATER_EQUAL: { FIXNUM_COMPARE_OP(>=); } break; |
211 | case OP_JUMP: { | 211 | case OP_JUMP: { |
212 | u16 a = *frame->pc++; | 212 | u16 a = *vm->pc++; |
213 | u16 b = *frame->pc++; | 213 | u16 b = *vm->pc++; |
214 | s16 offset = (a << 8) | b; | 214 | s16 offset = (a << 8) | b; |
215 | frame->pc += offset; | 215 | vm->pc += offset; |
216 | } break; | 216 | } break; |
217 | case OP_JUMP_IF_FALSE: { | 217 | case OP_JUMP_IF_FALSE: { |
218 | u16 a = *frame->pc++; | 218 | u16 a = *vm->pc++; |
219 | u16 b = *frame->pc++; | 219 | u16 b = *vm->pc++; |
220 | s16 offset = (a << 8) | b; | 220 | s16 offset = (a << 8) | b; |
221 | if (IS_FALSE(array_pop(vm->stack))) { | 221 | if (IS_FALSE(array_pop(vm->stack))) { |
222 | frame->pc += offset; | 222 | vm->pc += offset; |
223 | } | 223 | } |
224 | } break; | 224 | } break; |
225 | case OP_DISPLAY: { | 225 | case OP_DISPLAY: { |
@@ -253,15 +253,18 @@ vm_interpret(VM *vm) { | |||
253 | printf("\n"); | 253 | printf("\n"); |
254 | } break; | 254 | } break; |
255 | case OP_RETURN: { | 255 | case OP_RETURN: { |
256 | printf("\n"); | 256 | if (frame->rp != NULL) { |
257 | // TODO: restore previous call frame. | ||
258 | vm->pc = frame->rp; | ||
259 | } | ||
257 | return; | 260 | return; |
258 | } break; | 261 | } break; |
259 | default: { | 262 | default: { |
260 | error_push((Error){ | 263 | error_push((Error){ |
261 | .type = ERR_TYPE_RUNTIME, | 264 | .type = ERR_TYPE_RUNTIME, |
262 | .value = ERR_NOT_IMPLEMENTED, | 265 | .value = ERR_NOT_IMPLEMENTED, |
263 | .line = chunk->lines[frame->pc - chunk->code - 1].line, | 266 | .line = frame->chunk->lines[vm->pc - frame->chunk->code - 1].line, |
264 | .col = chunk->lines[frame->pc - chunk->code - 1].col, | 267 | .col = frame->chunk->lines[vm->pc - frame->chunk->code - 1].col, |
265 | }); | 268 | }); |
266 | return; | 269 | return; |
267 | } break; | 270 | } break; |
@@ -271,8 +274,8 @@ vm_interpret(VM *vm) { | |||
271 | error_push((Error){ | 274 | error_push((Error){ |
272 | .type = ERR_TYPE_RUNTIME, | 275 | .type = ERR_TYPE_RUNTIME, |
273 | .value = ERR_PC_OOB, | 276 | .value = ERR_PC_OOB, |
274 | .line = chunk->lines[0].line, | 277 | .line = frame->chunk->lines[0].line, |
275 | .col = chunk->lines[0].col, | 278 | .col = frame->chunk->lines[0].col, |
276 | }); | 279 | }); |
277 | } | 280 | } |
278 | 281 | ||