blueloveTH 2 лет назад
Родитель
Сommit
1a8877f28a
5 измененных файлов с 17 добавлено и 6 удалено
  1. 1 1
      c_bindings/test.c
  2. 1 1
      c_bindings/test_answers.txt
  3. 5 0
      include/pocketpy/error.h
  4. 1 1
      src/pocketpy.cpp
  5. 9 3
      src/pocketpy_c.cpp

+ 1 - 1
c_bindings/test.c

@@ -381,7 +381,7 @@ int main(int argc, char** argv) {
 
     //this should be catchable
     check(pkpy_exec(vm, "try : test_error_propagate(); except NameError : pass"));
-    error(pkpy_error(vm, "_", pkpy_string("test direct error mechanism")));
+    error(pkpy_error(vm, "Exception", pkpy_string("test direct error mechanism")));
 
     //more complicated error handling
     check(pkpy_exec(vm, "def error_from_python() : raise NotImplementedError()"));

+ 1 - 1
c_bindings/test_answers.txt

@@ -92,7 +92,7 @@ Traceback (most recent call last):
 NameError: catch me
 successfully errored with this message: 
 Traceback (most recent call last):
-_: test direct error mechanism
+Exception: test direct error mechanism
 successfully errored with this message: 
 Traceback (most recent call last):
   File "main.py", line 1

+ 5 - 0
include/pocketpy/error.h

@@ -62,6 +62,11 @@ struct Exception {
     stack<ExceptionLine> stacktrace;
     Exception(StrName type): type(type), is_re(true), _ip_on_error(-1), _code_on_error(nullptr), _self(nullptr) {}
 
+    PyObject* self(){
+        PK_ASSERT(_self != nullptr);
+        return _self;
+    }
+
     template<typename... Args>
     void st_push(Args&&... args){
         if(stacktrace.size() >= 8) return;

+ 1 - 1
src/pocketpy.cpp

@@ -1727,7 +1727,7 @@ CodeObject_ VM::compile(Str source, Str filename, CompileMode mode, bool unknown
 #if PK_DEBUG_FULL_EXCEPTION
         std::cerr << e.summary() << std::endl;
 #endif
-        _error(e._self);
+        _error(e.self());
         return nullptr;
     }
 }

+ 9 - 3
src/pocketpy_c.cpp

@@ -45,11 +45,12 @@ static PyObject* stack_item(VM* vm, int index){
 #define PK_PROTECTED(__B) \
     try{ __B }  \
     catch(const Exception& e ) { \
-        vm->_c.error = e._self; \
+        vm->_c.error = e.self(); \
         return false; \
     } catch(const std::exception& re){ \
         PyObject* e_t = vm->_t(vm->tp_exception); \
         vm->_c.error = vm->call(e_t, VAR(re.what())); \
+        PK_OBJ_GET(Exception, vm->_c.error)._self = vm->_c.error; \
         return false; \
     }
 
@@ -338,7 +339,7 @@ static PyObject* c_function_wrapper(VM* vm, ArgsView args) {
 
     // propagate_if_errored
     if (vm->_c.error != nullptr){
-        PyObject* e_obj = PK_OBJ_GET(Exception, vm->_c.error)._self;
+        PyObject* e_obj = PK_OBJ_GET(Exception, vm->_c.error).self();
         vm->_c.error = nullptr;
         vm->_error(e_obj);
         return nullptr;
@@ -495,8 +496,13 @@ bool pkpy_py_str(pkpy_vm* vm_handle) {
 bool pkpy_error(pkpy_vm* vm_handle, const char* name, pkpy_CString message) {
     VM* vm = (VM*) vm_handle;
     PK_ASSERT_NO_ERROR()
-    PyObject* e_t = vm->_t(vm->tp_exception);
+    PyObject* e_t = vm->builtins->attr().try_get_likely_found(name);
+    if(e_t == nullptr){
+        e_t = vm->_t(vm->tp_exception);
+        std::cerr << "[warning] pkpy_error(): " << Str(name).escape() << " not found, fallback to 'Exception'" << std::endl;
+    }
     vm->_c.error = vm->call(e_t, VAR(std::string_view(message.data, message.size)));
+    PK_OBJ_GET(Exception, vm->_c.error)._self = vm->_c.error;
     return false;
 }