diff --git a/port/linux/.vscode/launch.json b/port/linux/.vscode/launch.json index ae6d48eb8..734b5f64c 100644 --- a/port/linux/.vscode/launch.json +++ b/port/linux/.vscode/launch.json @@ -39,7 +39,10 @@ // "--gtest_filter=builtin.isinstance" // "--gtest_filter=bytes.bytes_split" // "--gtest_filter=except.dict" - "--gtest_filter=except.for_loop" + // "--gtest_filter=except.*" + "--gtest_filter=except.try1" + // "--gtest_filter=except.for_loop" + // "--gtest_filter=builtin.init_raise" ], "stopAtEntry": false, "cwd": "${workspaceFolder}", diff --git a/port/linux/test/module-test.cpp b/port/linux/test/module-test.cpp index e4d5ff361..471e96d06 100644 --- a/port/linux/test/module-test.cpp +++ b/port/linux/test/module-test.cpp @@ -1,7 +1,7 @@ -#include "test_common.h" -#include -#include #include +#include +#include +#include "test_common.h" TEST_START #if PIKA_SYNTAX_IMPORT_EX_ENABLE TEST(module, cmodule_import) { @@ -299,9 +299,11 @@ TEST_RUN_SINGLE_FILE_ASSERT(socket, "test/python/socket/socket_GET.py", obj_getBool(pikaMain, "res") == pika_true) +#if 0 // offen fail because of network TEST_RUN_SINGLE_FILE_PASS(socket, socket_DNS, "test/python/socket/socket_DNS.py") +#endif #endif diff --git a/src/PikaObj.c b/src/PikaObj.c index 5ed51f5a6..eb2e21a9c 100644 --- a/src/PikaObj.c +++ b/src/PikaObj.c @@ -202,13 +202,14 @@ int32_t obj_deinit(PikaObj* self) { Arg* del = obj_getMethodArgWithFullPath(self, "__del__"); if (NULL != del) { obj_setFlag(self, OBJ_FLAG_IN_DEL); - PikaVMThread* thread = pikaVMThread_require(); - thread->in_del_call = 1; + // PikaVMThread* vmThread = pikaVMThread_require(); + // pika_assert(NULL != vmThread); + // vmThread->in_del_call = 1; Arg* aRes = obj_runMethodArg0(self, del); if (NULL != aRes) { arg_deinit(aRes); } - thread->in_del_call = 0; + // vmThread->in_del_call = 0; } extern volatile PikaObj* __pikaMain; if (self == (PikaObj*)__pikaMain) { @@ -4345,7 +4346,7 @@ void _do_vsysOut(char* fmt, va_list args) { void obj_setSysOut(PikaObj* self, char* fmt, ...) { if (NULL != self->vmFrame) { - if (self->vmFrame->error.code == 0) { + if (self->vmFrame->error.code == PIKA_RES_OK) { self->vmFrame->error.code = PIKA_RES_ERR_RUNTIME_ERROR; } if (self->vmFrame->vm_thread->try_state == TRY_STATE_INNER) { diff --git a/src/PikaObj.h b/src/PikaObj.h index d3adbd0ac..4836c0b97 100644 --- a/src/PikaObj.h +++ b/src/PikaObj.h @@ -122,6 +122,7 @@ struct PikaVMThread { TRY_STATE try_state; TRY_RESULT try_result; PikaVMError* error_stack; + PikaVMError* exception_stack; uint32_t error_stack_deepth; uint32_t error_stack_deepth_max; uint8_t invoke_deepth; diff --git a/src/PikaVM.c b/src/PikaVM.c index 06bda4cf5..de4391efe 100644 --- a/src/PikaVM.c +++ b/src/PikaVM.c @@ -462,7 +462,7 @@ static void PikaVMFrame_setErrorCode(PikaVMFrame* vm, int8_t error_code) { void _do_vsysOut(char* fmt, va_list args); void PikaVMFrame_setSysOut(PikaVMFrame* vm, char* fmt, ...) { pika_assert(NULL != vm); - if (vm->error.code == 0) { + if (vm->error.code == PIKA_RES_OK) { vm->error.code = PIKA_RES_ERR_RUNTIME_ERROR; } if (vm->vm_thread->try_state == TRY_STATE_INNER) { @@ -990,7 +990,7 @@ static Arg* VM_instruction_handler_EXP(PikaObj* self, PikaVMFrame* vm, char* data, Arg* arg_ret_reg) { - pikaVMThread_clearErrorStack(vm->vm_thread); + pikaVMThread_clearExceptionStack(vm->vm_thread); return NULL; } @@ -999,6 +999,7 @@ static Arg* VM_instruction_handler_NTR(PikaObj* self, char* data, Arg* arg_ret_reg) { vm->vm_thread->try_state = TRY_STATE_NONE; + pikaVMThread_convertExceptionStack(vm->vm_thread); return NULL; } @@ -1171,8 +1172,7 @@ static Arg* VM_instruction_handler_GER(PikaObj* self, PikaVMFrame* vm, char* data, Arg* arg_ret_reg) { - PikaVMThread* vm_thread = pikaVMThread_require(); - PIKA_RES err = pikaVMThread_checkErrorCode(vm_thread); + PIKA_RES err = pikaVMFrame_checkExceptionStack(vm); Arg* err_arg = arg_newInt(err); return err_arg; } @@ -2188,7 +2188,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, vm, oThis, oSublocals->list, aMethod, sRunPath, sProxyName, iNumUsed); /* load args failed */ - if (pikaVMFrame_checkErrorCode(vm) != 0) { + if (pikaVMFrame_checkErrorStack(vm) != PIKA_RES_OK) { goto __exit; } @@ -2224,7 +2224,7 @@ static Arg* VM_instruction_handler_RUN(PikaObj* self, PikaVMFrame_loadArgsFromMethodArg(vm, oNew, oSublocalsInit->list, aMethod, "__init__", NULL, iNumUsed); /* load args failed */ - if (pikaVMFrame_checkErrorCode(vm) != 0) { + if (pikaVMFrame_checkErrorStack(vm) != PIKA_RES_OK) { goto __init_exit; } aReturnInit = obj_runMethodArgWithState(oNew, oSublocalsInit, aMethod, @@ -3776,7 +3776,7 @@ static int pikaVM_runInstructUnit(PikaObj* self, return_arg = VM_instruct_handler_table[instruct](self, vm, data, &ret_reg); #endif - if (pikaVMFrame_checkErrorCode(vm) != PIKA_RES_OK || + if (pikaVMFrame_checkErrorStack(vm) != PIKA_RES_OK || VMSignal_getCtrl() == VM_SIGNAL_CTRL_EXIT) { /* raise jmp */ if (vm->vm_thread->try_state == TRY_STATE_INNER) { @@ -3842,7 +3842,7 @@ __next_line: pc_next = vm->pc + instructUnit_getSize(); /* jump to next line */ - if (pikaVMFrame_checkErrorCode(vm) != 0) { + if (pikaVMFrame_checkErrorStack(vm) != PIKA_RES_OK) { while (1) { if (pc_next >= (int)PikaVMFrame_getInstructArraySize(vm)) { pc_next = VM_PC_EXIT; @@ -4527,42 +4527,39 @@ PikaVMFrame* PikaVMFrame_create(VMParameters* locals, } int PikaVMFrame_destroy(PikaVMFrame* vm) { - // if (pikaVMError_isNone(vm->error)) { - if (1) { - PikaVMError* err = pikaVMThread_popError(vm->vm_thread); - if (NULL != err) { - pikaFree(err, sizeof(PikaVMError)); - } - } + // PikaVMError* err = pikaVMThread_popError(vm->vm_thread); + // if (NULL != err) { + // pikaFree(err, sizeof(PikaVMError)); + // } stack_deinit(&(vm->stack)); pikaFree(vm, sizeof(PikaVMFrame)); return 0; } -int pikaVMError_isNone(PikaVMError* error) { - return error->code == 0 && error->line_code == 0; -} - int pikaVMFrame_checkErrorCode(PikaVMFrame* state) { pika_assert(NULL != state); return state->error.code; } -int pikaVMThread_checkErrorCode(PikaVMThread* vmThread) { - pika_assert(NULL != vmThread); - if (NULL == vmThread->error_stack) { +int pikaVMFrame_checkErrorStack(PikaVMFrame* vm) { + pika_assert(NULL != vm); + PIKA_RES code = pikaVMFrame_checkErrorCode(vm); + if (code != PIKA_RES_OK) { + return code; + } + if (NULL == vm->vm_thread->error_stack) { return 0; } - // if (state->in_del_call) { - if (1) { - if (0 != vmThread->error_stack->code) { - return vmThread->error_stack->code; + if (vm->vm_thread->in_del_call) { + if (0 != vm->vm_thread->error_stack->code) { + return vm->vm_thread->error_stack->code; } else { return 0; } } - for (PikaVMError* current = vmThread->error_stack; current != NULL; + + for (PikaVMError* current = vm->vm_thread->error_stack; current != NULL; current = current->next) { if (0 != current->code) { return current->code; @@ -4571,10 +4568,24 @@ int pikaVMThread_checkErrorCode(PikaVMThread* vmThread) { return 0; } -int pikaVMThread_pushError(PikaVMThread* state, PikaVMError* error) { - pika_assert(NULL != state); +int pikaVMFrame_checkExceptionStack(PikaVMFrame* vm) { + pika_assert(NULL != vm); + if (NULL == vm->vm_thread->exception_stack) { + return 0; + } + for (PikaVMError* current = vm->vm_thread->exception_stack; current != NULL; + current = current->next) { + if (0 != current->code) { + return current->code; + } + } + return 0; +} + +int pikaVMThread_pushError(PikaVMThread* vmThread, PikaVMError* error) { + pika_assert(NULL != vmThread); pika_assert(NULL != error); - for (PikaVMError* current = state->error_stack; current != NULL; + for (PikaVMError* current = vmThread->error_stack; current != NULL; current = current->next) { if (current == error) { return 0; @@ -4586,41 +4597,64 @@ int pikaVMThread_pushError(PikaVMThread* state, PikaVMError* error) { return -1; } pika_platform_memcpy(error_new, error, sizeof(PikaVMError)); - error_new->next = state->error_stack; - state->error_stack = error_new; - state->error_stack_deepth++; - if (state->error_stack_deepth > state->error_stack_deepth_max) { - state->error_stack_deepth_max = state->error_stack_deepth; + error_new->next = vmThread->error_stack; + vmThread->error_stack = error_new; + vmThread->error_stack_deepth++; + if (vmThread->error_stack_deepth > vmThread->error_stack_deepth_max) { + vmThread->error_stack_deepth_max = vmThread->error_stack_deepth; } return 0; } -PikaVMError* pikaVMThread_popError(PikaVMThread* state) { - pika_assert(NULL != state); - PikaVMError* error = state->error_stack; +PikaVMError* pikaVMThread_popError(PikaVMThread* vmThread) { + pika_assert(NULL != vmThread); + PikaVMError* error = vmThread->error_stack; if (error != NULL) { - state->error_stack = error->next; - state->error_stack_deepth--; + vmThread->error_stack = error->next; + vmThread->error_stack_deepth--; } return error; } -PikaVMError* pikaVMThread_getErrorCurrent(PikaVMThread* state) { - pika_assert(NULL != state); - return state->error_stack; +PikaVMError* pikaVMThread_getErrorCurrent(PikaVMThread* vmThread) { + pika_assert(NULL != vmThread); + return vmThread->error_stack; } -int pikaVMThread_clearErrorStack(PikaVMThread* state) { - pika_assert(NULL != state); - PikaVMError* current = state->error_stack; +int pikaVMThread_clearErrorStack(PikaVMThread* vmThread) { + pika_assert(NULL != vmThread); + PikaVMError* current = vmThread->error_stack; while (current != NULL) { PikaVMError* next = current->next; pikaFree(current, sizeof(PikaVMError)); - state->error_stack_deepth--; + vmThread->error_stack_deepth--; current = next; } - pika_assert(state->error_stack_deepth == 0); - state->error_stack = NULL; + pika_assert(vmThread->error_stack_deepth == 0); + vmThread->error_stack = NULL; + return 0; +} + +int pikaVMThread_clearExceptionStack(PikaVMThread* vmThread) { + pika_assert(NULL != vmThread); + PikaVMError* current = vmThread->exception_stack; + while (current != NULL) { + PikaVMError* next = current->next; + pikaFree(current, sizeof(PikaVMError)); + current = next; + } + vmThread->exception_stack = NULL; + return 0; +} + +int pikaVMThread_convertExceptionStack(PikaVMThread* vmThread) { + // Convert error stack to exception stack + pika_assert(NULL != vmThread); + if (NULL != vmThread->error_stack) { + vmThread->exception_stack = vmThread->error_stack; + } + vmThread->error_stack_deepth = 0; + vmThread->error_stack = NULL; return 0; } @@ -4667,7 +4701,12 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState( if (vm->ins_cnt % PIKA_INSTRUCT_YIELD_PERIOD == 0) { _pikaVM_yield(); } - if (vm->error.code != 0) { + // push vm frame error to thread error stack + if (pikaVMFrame_checkErrorCode(vm) != PIKA_RES_OK) { + pikaVMThread_pushError(vm->vm_thread, &(vm->error)); + } + // handle error + if (pikaVMFrame_checkErrorStack(vm) != PIKA_RES_OK) { vm->error.line_code = vm->error.code; InstructUnit* head_ins_unit = this_ins_unit; /* get first ins of a line */ @@ -4677,12 +4716,7 @@ static VMParameters* __pikaVM_runByteCodeFrameWithState( } head_ins_unit--; } - if (vm->vm_thread->try_state == TRY_STATE_INNER) { - // Store the error code in the try state - pikaVMThread_pushError(vm->vm_thread, &(vm->error)); - } - /* print inses of a line */ - if (!vm->vm_thread->try_state) { + if (vm->vm_thread->try_state == TRY_STATE_NONE) { while (1) { if (head_ins_unit != this_ins_unit) { pika_platform_printf(" "); @@ -4784,12 +4818,13 @@ static VMParameters* _pikaVM_runByteCodeFrameWithState( self, locals, globals, bytecode_frame, pc, vm_thread, pika_false); } -static PikaVMThread* pika_vm_state_head = NULL; +static PikaVMThread* g_pika_vm_state_head = NULL; int pikaVMThread_init(PikaVMThread* state, uint64_t thread_id) { state->thread_id = thread_id; state->invoke_deepth = 0; state->error_stack = NULL; + state->exception_stack = NULL; state->error_stack_deepth = 0; state->error_stack_deepth_max = 0; state->in_del_call = 0; @@ -4810,13 +4845,14 @@ PikaVMThread* pikaVMThread_create(uint64_t thread_id) { void pikaVMThread_destroy(PikaVMThread* state) { pikaVMThread_clearErrorStack(state); + pikaVMThread_clearExceptionStack(state); if (state != NULL) { pikaFree(state, sizeof(PikaVMThread)); } } PikaVMThread* pikaVMThread_find_node_by_thread_id(uint64_t thread_id) { - PikaVMThread* current = pika_vm_state_head; + PikaVMThread* current = g_pika_vm_state_head; while (current != NULL) { if (current->thread_id == thread_id) { return current; @@ -4839,21 +4875,21 @@ PikaVMThread* pikaVMThread_require(void) { return NULL; } - new_state->next = pika_vm_state_head; - pika_vm_state_head = new_state; + new_state->next = g_pika_vm_state_head; + g_pika_vm_state_head = new_state; return new_state; } void pikaVMThread_delete(void) { uint64_t current_thread_id = pika_platform_thread_self(); - PikaVMThread* current = pika_vm_state_head; + PikaVMThread* current = g_pika_vm_state_head; PikaVMThread* previous = NULL; while (current != NULL) { if (current->thread_id == current_thread_id) { if (previous == NULL) { - pika_vm_state_head = current->next; + g_pika_vm_state_head = current->next; } else { previous->next = current->next; } diff --git a/src/PikaVM.h b/src/PikaVM.h index a2d07477c..907d5f629 100644 --- a/src/PikaVM.h +++ b/src/PikaVM.h @@ -325,10 +325,12 @@ PikaVMThread* pikaVMThread_require(void); void pikaVMThread_delete(void); int pikaVMThread_pushError(PikaVMThread* state, PikaVMError* error); PikaVMError* pikaVMThread_popError(PikaVMThread* state); -int pikaVMError_isNone(PikaVMError* error); -int pikaVMThread_clearErrorStack(PikaVMThread* state); int pikaVMFrame_checkErrorCode(PikaVMFrame* state); -int pikaVMThread_checkErrorCode(PikaVMThread* state); +int pikaVMFrame_checkErrorStack(PikaVMFrame* vm); +int pikaVMThread_clearErrorStack(PikaVMThread* state); +int pikaVMThread_clearExceptionStack(PikaVMThread* vmThread); +int pikaVMFrame_checkExceptionStack(PikaVMFrame* vm); +int pikaVMThread_convertExceptionStack(PikaVMThread* vmThread); PikaVMError* pikaVMThread_getErrorCurrent(PikaVMThread* state); InstructUnit* instructArray_getNow(InstructArray* self); InstructUnit* instructArray_getNext(InstructArray* self); diff --git a/src/PikaVersion.h b/src/PikaVersion.h index 38cd45c87..92cf4e1c9 100644 --- a/src/PikaVersion.h +++ b/src/PikaVersion.h @@ -2,4 +2,4 @@ #define PIKA_VERSION_MINOR 13 #define PIKA_VERSION_MICRO 3 -#define PIKA_EDIT_TIME "2024/08/08 22:29:41" +#define PIKA_EDIT_TIME "2024/08/09 00:41:14"