diff options
Diffstat (limited to 'src/bytecode/vm.h')
-rwxr-xr-x | src/bytecode/vm.h | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/src/bytecode/vm.h b/src/bytecode/vm.h index 84d2432..287c83c 100755 --- a/src/bytecode/vm.h +++ b/src/bytecode/vm.h | |||
@@ -188,6 +188,13 @@ vm_interpret(VM *vm) { | |||
188 | ssize_t idx = AS_FIXNUM(array_pop(vm->stack)); | 188 | ssize_t idx = AS_FIXNUM(array_pop(vm->stack)); |
189 | vm->stack[frame->stack_offset + idx] = value; | 189 | vm->stack[frame->stack_offset + idx] = value; |
190 | } break; | 190 | } break; |
191 | case OP_SET_LOCAL: { | ||
192 | Object value = array_pop(vm->stack); | ||
193 | ssize_t idx = AS_FIXNUM(array_pop(vm->stack)); | ||
194 | ssize_t depth = AS_FIXNUM(array_pop(vm->stack)); | ||
195 | CallFrame frame = vm->frames[depth]; | ||
196 | vm->stack[frame.stack_offset + idx] = value; | ||
197 | } break; | ||
191 | case OP_DEF: { | 198 | case OP_DEF: { |
192 | Object value = array_pop(vm->stack); | 199 | Object value = array_pop(vm->stack); |
193 | Object name = array_pop(vm->stack); | 200 | Object name = array_pop(vm->stack); |
@@ -280,13 +287,13 @@ vm_interpret(VM *vm) { | |||
280 | // Check the number of arguments is correct. | 287 | // Check the number of arguments is correct. |
281 | // NOTE: This is probably better handled at compilation, but for | 288 | // NOTE: This is probably better handled at compilation, but for |
282 | // now this is simpler to implement. | 289 | // now this is simpler to implement. |
283 | ssize_t n_params = array_size(proc.chunk->params); | 290 | ssize_t n_params = proc.chunk->n_params; |
291 | ssize_t n_locals = proc.chunk->n_locals; | ||
284 | if (n_args < n_params) { | 292 | if (n_args < n_params) { |
285 | RUNTIME_ERROR(ERR_NOT_ENOUGH_ARGS); | 293 | RUNTIME_ERROR(ERR_NOT_ENOUGH_ARGS); |
286 | } else if (n_args > n_params) { | 294 | } else if (n_args > n_params) { |
287 | RUNTIME_ERROR(ERR_TOO_MANY_ARGS); | 295 | RUNTIME_ERROR(ERR_TOO_MANY_ARGS); |
288 | } | 296 | } |
289 | ssize_t n_locals = array_size(proc.chunk->locals) - n_params; | ||
290 | 297 | ||
291 | #ifdef DEBUG | 298 | #ifdef DEBUG |
292 | disassemble_chunk(proc.chunk); | 299 | disassemble_chunk(proc.chunk); |
@@ -298,7 +305,7 @@ vm_interpret(VM *vm) { | |||
298 | CallFrame new_frame = (CallFrame){ | 305 | CallFrame new_frame = (CallFrame){ |
299 | .chunk = proc.chunk, | 306 | .chunk = proc.chunk, |
300 | .rp = vm->pc, | 307 | .rp = vm->pc, |
301 | .stack_offset = array_size(vm->stack) - array_size(proc.chunk->params), | 308 | .stack_offset = array_size(vm->stack) - n_params, |
302 | }; | 309 | }; |
303 | array_push(vm->frames, new_frame); | 310 | array_push(vm->frames, new_frame); |
304 | frame = &vm->frames[array_size(vm->frames) - 1]; | 311 | frame = &vm->frames[array_size(vm->frames) - 1]; |
@@ -315,7 +322,8 @@ vm_interpret(VM *vm) { | |||
315 | } | 322 | } |
316 | 323 | ||
317 | // Reset stack size. | 324 | // Reset stack size. |
318 | array_head(vm->stack)->size = frame->stack_offset + n_params + n_locals; | 325 | size_t offset = frame->stack_offset + n_params + n_locals; |
326 | array_head(vm->stack)->size = offset; | ||
319 | } | 327 | } |
320 | vm->pc = frame->chunk->code; | 328 | vm->pc = frame->chunk->code; |
321 | } break; | 329 | } break; |