From 6f264e22b62e7f80d481d498ab15fd4f18835c94 Mon Sep 17 00:00:00 2001 From: hiperiondev Date: Fri, 30 Aug 2024 21:12:02 -0300 Subject: [PATCH] Correct generic heap object. Add test --- test/test.c | 24 +++++++++++++++++++++++- vm/vm.c | 40 +++++++++++++++++++++++++++++----------- 2 files changed, 52 insertions(+), 12 deletions(-) diff --git a/test/test.c b/test/test.c index a01a8f2..56d8a62 100644 --- a/test/test.c +++ b/test/test.c @@ -1318,7 +1318,7 @@ void test_opcodes(void) { END_TEST(); free(externals.lib); /////////////////////////////////// - START_TEST(STRING LIBRARY: STATIC LIB OBJECT,// + START_TEST(TEST LIBRARY: STATIC LIB OBJECT,// "CALL 0 fn\n" // "GET_RETVAL\n" // "LIB_FN 0 9\n" // LIBTEST_FN_TEST0 @@ -1343,6 +1343,28 @@ void test_opcodes(void) { END_TEST(); free(externals.lib); /////////////////////////////////// + START_TEST(GENERIC OBJECT, // + "CALL 0 fn\n" // + "GET_GLOBAL 0\n" // + "PUSH_HEAP_OBJECT\n" // + "GET_GLOBAL 0\n" // + "FREE_HEAP_OBJECT\n" // + "HALT 99\n" // end + ".label fn\n" // + "PUSH_UINT 97\n" // + "@NEW_HEAP_OBJECT\n" // push new generic object (static) + "SET_GLOBAL 0\n" // + "RETURN\n" // + ); // + + TEST_EXECUTE; + OP_TEST_START(19, 1, 0); + vm_value = vm_pop(&thread); + assert(vm_value.type == VM_VAL_UINT); + assert(vm_value.number.uinteger == 97); + OP_TEST_END(); + END_TEST(); + /////////////////////////////////// printf("---( tests: %u / fails: %u )---\n", tests_qty, tests_fails); printf("---[ END TEST OPCODES ]---\n"); diff --git a/vm/vm.c b/vm/vm.c index f0e610d..bd98b04 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -148,8 +148,9 @@ void vm_step(vm_thread_t **thread, vm_program_t *program) { vm_value_t value = vm_pop(thread); vm_heap_object_t obj; vm_value_t ref; + bool is_new_lib = program->prog[(*thread)->pc - 1] == NEW_LIB_OBJ ? true : false; - if (program->prog[(*thread)->pc - 1] == NEW_LIB_OBJ) { + if (is_new_lib) { if (value.type != VM_VAL_UINT || value.number.uinteger > (*thread)->externals->lib_qty) { err = VM_ERR_BAD_VALUE; break; @@ -163,7 +164,7 @@ void vm_step(vm_thread_t **thread, vm_program_t *program) { obj.lib_obj.addr = NULL; obj.lib_obj.lib_idx = value.number.uinteger; } else { - ref.type = VM_VAL_GENERIC; + ref.type = VM_VAL_HEAP_REF; obj.type = VM_VAL_GENERIC; obj.static_obj = false; @@ -174,19 +175,31 @@ void vm_step(vm_thread_t **thread, vm_program_t *program) { obj.static_obj = true; uint32_t heap_ref = vm_heap_save((*thread)->heap, obj, &((*thread)->frames[(*thread)->fc].gc_mark)); - ref.lib_obj.heap_ref = heap_ref; - vm_push(thread, ref); - (*thread)->externals->lib[value.number.uinteger](thread, VM_EDFAT_NEW, value.number.uinteger, heap_ref); + + if (is_new_lib) { + ref.lib_obj.heap_ref = heap_ref; + vm_push(thread, ref); + (*thread)->externals->lib[value.number.uinteger](thread, VM_EDFAT_NEW, value.number.uinteger, heap_ref); + } else { + ref.heap_ref = heap_ref; + vm_push(thread, ref); + } + } break; case PUSH_HEAP_OBJECT: { vm_value_t value = STK_TOP(thread); - if (value.type != VM_VAL_UINT) + if (value.type != VM_VAL_LIB_OBJ && value.type != VM_VAL_HEAP_REF) err = VM_ERR_BAD_VALUE; else { - uint32_t idx = value.number.uinteger; + uint32_t idx; + if (value.type == VM_VAL_LIB_OBJ) + idx = value.lib_obj.heap_ref; + else + idx = value.heap_ref; + vm_heap_object_t *obj = vm_heap_load((*thread)->heap, idx); if (obj->type == VM_VAL_NULL) err = VM_ERR_HEAPNOTEXIST; @@ -213,13 +226,18 @@ void vm_step(vm_thread_t **thread, vm_program_t *program) { break; case FREE_HEAP_OBJECT: { - vm_value_t value = STK_TOP(thread); + vm_value_t value = vm_pop(thread); - if (value.type != VM_VAL_UINT) { + if (value.type != VM_VAL_LIB_OBJ && value.type != VM_VAL_HEAP_REF) { err = VM_ERR_BAD_VALUE; } else { - uint32_t idx = value.number.uinteger; - vm_heap_free((*thread)->heap, idx); + uint32_t idx; + if (value.type == VM_VAL_LIB_OBJ) { + idx = value.lib_obj.heap_ref; + } else { + idx = value.heap_ref; + vm_heap_free((*thread)->heap, idx); + } } } break;