diff --git a/Makefile b/Makefile index 8744b71..deadffc 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ build-release: cmake --build build $(COMPARING) debug-c: build - gdb --args ./build/fzc ${FILE} + gdb --args ./build/fzc -v ${FILE} debug-vm: build gdb --args ./build/fz ${FILE} diff --git a/include/vm/internals/opcode.h b/include/vm/internals/opcode.h index 4a8d801..7dec73f 100644 --- a/include/vm/internals/opcode.h +++ b/include/vm/internals/opcode.h @@ -13,6 +13,8 @@ extern size_t total_jmp_on_same; void print_object(fzl_vm_object_t *obj); void print_err_data(fzl_vm_t *vm); +void escape_recursive(fzl_vm_env_t *current, fzl_vm_env_t *parent, + fzl_vm_object_t *obj); // --- stack --- diff --git a/src/vm/handlers/group_ctx.c b/src/vm/handlers/group_ctx.c index edbdc46..251035c 100644 --- a/src/vm/handlers/group_ctx.c +++ b/src/vm/handlers/group_ctx.c @@ -1,3 +1,4 @@ +#include "common/fzl_types.h" #include #include #include @@ -136,7 +137,8 @@ int op_load_local(fzl_vm_t *vm) if (depth >= vm->etop) { - snprintf(last_err, sizeof(last_err), "runtime error - local depth out of range"); + snprintf(last_err, sizeof(last_err), + "runtime error - local depth out of range"); print_err_data(vm); return -1; } @@ -144,7 +146,8 @@ int op_load_local(fzl_vm_t *vm) fzl_vm_env_t *env = vm->estack[vm->etop - 1 - depth]; if (env->size <= slot) { - snprintf(last_err, sizeof(last_err), "runtime error - local slot out of range"); + snprintf(last_err, sizeof(last_err), + "runtime error - local slot out of range"); print_err_data(vm); return -1; } @@ -170,7 +173,8 @@ int op_store_local(fzl_vm_t *vm) if (depth >= vm->etop) { - snprintf(last_err, sizeof(last_err), "runtime error - local depth out of range"); + snprintf(last_err, sizeof(last_err), + "runtime error - local depth out of range"); print_err_data(vm); return -1; } @@ -178,11 +182,21 @@ int op_store_local(fzl_vm_t *vm) fzl_vm_env_t *env = vm->estack[vm->etop - 1 - depth]; if (env->size <= slot) { - snprintf(last_err, sizeof(last_err), "runtime error - local slot out of range"); + snprintf(last_err, sizeof(last_err), + "runtime error - local slot out of range"); print_err_data(vm); return -1; } + if (value.type == FZL_TYPE_OBJECT && depth != 0) + { + for (size_t i = 0; i < depth; i++) + { + escape_recursive(vm->estack[vm->etop - i], vm->estack[vm->etop - 1 - i], + value.as.obj); + } + } + env->table[slot].value = value; return 0; } diff --git a/src/vm/handlers/group_obj.c b/src/vm/handlers/group_obj.c index ae02cb8..d090305 100644 --- a/src/vm/handlers/group_obj.c +++ b/src/vm/handlers/group_obj.c @@ -4,8 +4,8 @@ #include // Escape objects with nested objects check -static void escape_recursive(fzl_vm_env_t *current, fzl_vm_env_t *parent, - fzl_vm_object_t *obj) +void escape_recursive(fzl_vm_env_t *current, fzl_vm_env_t *parent, + fzl_vm_object_t *obj) { if (!current || !parent || !obj) return; @@ -60,8 +60,10 @@ int op_alloc_object(fzl_vm_t *vm) uint64_t values_count = vm->ops[++vm->ip]; fzl_vm_object_t *obj = malloc(sizeof(fzl_vm_object_t)); - if (values_count > 0) - obj->values = malloc(values_count * sizeof(fzl_value_t)); + if (values_count < 1) + values_count = 1; + + obj->values = malloc(values_count * sizeof(fzl_value_t)); obj->values_count = values_count; memset(obj->values, 0, values_count * sizeof(fzl_value_t)); diff --git a/tests/programs/pos_objs_in_loop.fzs b/tests/programs/pos_objs_in_loop.fzs new file mode 100644 index 0000000..10effe6 --- /dev/null +++ b/tests/programs/pos_objs_in_loop.fzs @@ -0,0 +1,12 @@ +class SomeObj {} + +SomeObj obj; + +for (int i = 0; i < 1; i = i + 1) +{ + obj = new SomeObj; +} + +bool not_null = (obj != null); +printline($"The object {obj} is not null? - {not_null}"); +