瀏覽代碼

move error.h

blueloveTH 1 年之前
父節點
當前提交
3a257aefb1

+ 2 - 0
include/pocketpy/common/strname.h

@@ -7,6 +7,8 @@
 extern "C" {
 #endif
 
+typedef uint16_t pkpy_StrName;
+
 uint16_t pkpy_StrName__map(const char*);
 uint16_t pkpy_StrName__map2(c11_string);
 const char* pkpy_StrName__rmap(uint16_t index);

+ 0 - 6
include/pocketpy/objects/base.hpp

@@ -4,12 +4,6 @@
 #include "pocketpy/common/traits.hpp"
 #include "pocketpy/objects/base.h"
 
-#include <cstddef>
-#include <cstdint>
-#include <cassert>
-#include <cstdlib>
-#include <cstring>
-
 namespace pkpy {
 
 struct Type {

+ 39 - 0
include/pocketpy/objects/error.h

@@ -0,0 +1,39 @@
+#pragma once
+
+#include "pocketpy/common/str.h"
+#include "pocketpy/common/strname.h"
+#include "pocketpy/objects/sourcedata.h"
+#include "pocketpy/objects/object.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct pkpy_ExceptionFrame {
+    pkpy_SourceData_ src;
+    int lineno;
+    const char* cursor;
+    pkpy_Str name;
+} pkpy_ExceptionFrame;
+
+typedef struct pkpy_Exception {
+    pkpy_StrName type;
+    pkpy_Str msg;
+    bool is_re;
+
+    int _ip_on_error;
+    void* _code_on_error;
+
+    PyObject* self;  // weak reference
+
+    c11_vector/*T=pkpy_ExceptionFrame*/ stacktrace;
+} pkpy_Exception;
+
+void pkpy_Exception__ctor(pkpy_Exception* self, pkpy_StrName type);
+void pkpy_Exception__dtor(pkpy_Exception* self);
+void pkpy_Exception__stpush(pkpy_Exception* self, pkpy_SourceData_ src, int lineno, const char* cursor, const char* name);
+pkpy_Str pkpy_Exception__summary(pkpy_Exception* self);
+
+#ifdef __cplusplus
+}
+#endif

+ 16 - 52
include/pocketpy/objects/error.hpp

@@ -1,7 +1,9 @@
 #pragma once
 
 #include "pocketpy/common/str.hpp"
+#include "pocketpy/common/traits.hpp"
 #include "pocketpy/objects/sourcedata.h"
+#include "pocketpy/objects/error.h"
 
 namespace pkpy {
 
@@ -22,62 +24,24 @@ struct InternalException final {
     InternalException(InternalExceptionType type, int arg = -1) : type(type), arg(arg) {}
 };
 
-struct Exception {
-    StrName type;
-    Str msg;
-    bool is_re;
-
-    int _ip_on_error;
-    void* _code_on_error;
-
-    PyObject* _self;  // weak reference
-
-    struct Frame {
-        pkpy_SourceData_ src;
-        int lineno;
-        const char* cursor;
-        std::string name;
-
-        Str snapshot() const {
-            return pkpy_SourceData__snapshot(src, lineno, cursor, name.empty() ? nullptr : name.c_str());
-        }
-
-        Frame(pkpy_SourceData_ src, int lineno, const char* cursor, std::string_view name) :
-            src(src), lineno(lineno), cursor(cursor), name(name) {
-                PK_INCREF(src);
-            }
-        // disable copy
-        Frame(const Frame&) = delete;
-        // allow move
-        Frame(Frame&& other) noexcept{
-            src = other.src;
-            lineno = other.lineno;
-            cursor = other.cursor;
-            name = std::move(other.name);
-            other.src = nullptr;
-        }
-
-        ~Frame() {
-            if(src) PK_DECREF(src);
-        }
-    };
-
-    vector<Frame> stacktrace;
-
-    Exception(StrName type) : type(type), is_re(true), _ip_on_error(-1), _code_on_error(nullptr), _self(nullptr) {}
-
-    PyObject* self() const {
-        assert(_self != nullptr);
-        return _self;
+struct Exception: pkpy_Exception{
+    PK_ALWAYS_PASS_BY_POINTER(Exception)
+
+    Exception(uint16_t type){
+        pkpy_Exception__ctor(this, type);
+    }
+
+    ~Exception(){
+        pkpy_Exception__dtor(this);
     }
 
-    template <typename... Args>
-    void st_push(Args&&... args) {
-        if(stacktrace.size() >= 7) return;
-        stacktrace.emplace_back(std::forward<Args>(args)...);
+    void stpush(pkpy_SourceData_ src, int lineno, const char* cursor, const char* name){
+        pkpy_Exception__stpush(this, src, lineno, cursor, name);
     }
 
-    Str summary() const;
+    Str summary(){
+        return pkpy_Exception__summary(this);
+    }
 };
 
 struct TopLevelException : std::exception {

+ 1 - 1
src/common/sourcedata.c

@@ -77,7 +77,7 @@ pkpy_Str pkpy_SourceData__snapshot(const struct pkpy_SourceData* self, int linen
         lineno
     );
 
-    if(name) {
+    if(name && *name) {
         pkpy_SStream__write_cstr(&ss, ", in ");
         pkpy_SStream__write_cstr(&ss, name);
     }

+ 59 - 0
src/error.c

@@ -0,0 +1,59 @@
+#include "pocketpy/objects/error.h"
+#include "pocketpy/common/strname.h"
+#include "pocketpy/common/sstream.h"
+
+void pkpy_Exception__ctor(pkpy_Exception* self, pkpy_StrName type){
+    self->type = type;
+    self->is_re = true;
+    self->_ip_on_error = -1;
+    self->_code_on_error = NULL;
+    self->self = NULL;
+
+    pkpy_Str__ctor(&self->msg, "");
+    c11_vector__ctor(&self->stacktrace, sizeof(pkpy_ExceptionFrame));
+}
+
+void pkpy_Exception__dtor(pkpy_Exception* self){
+    for(int i=0; i<self->stacktrace.count; i++){
+        pkpy_ExceptionFrame* frame = c11__at(pkpy_ExceptionFrame, &self->stacktrace, i);
+        PK_DECREF(frame->src);
+        pkpy_Str__dtor(&frame->name);
+    }
+    pkpy_Str__dtor(&self->msg);
+    c11_vector__dtor(&self->stacktrace);
+}
+
+void pkpy_Exception__stpush(pkpy_Exception* self, pkpy_SourceData_ src, int lineno, const char* cursor, const char* name){
+    if(self->stacktrace.count >= 7) return;
+    PK_INCREF(src);
+    pkpy_ExceptionFrame* frame = c11_vector__emplace(&self->stacktrace);
+    frame->src = src;
+    frame->lineno = lineno;
+    frame->cursor = cursor;
+    pkpy_Str__ctor(&frame->name, name);
+}
+
+pkpy_Str pkpy_Exception__summary(pkpy_Exception* self){
+    pkpy_SStream ss;
+    pkpy_SStream__ctor(&ss);
+
+    if(self->is_re){
+        pkpy_SStream__write_cstr(&ss, "Traceback (most recent call last):\n");
+    }
+    for(int i=self->stacktrace.count-1; i >= 0; i--) {
+        pkpy_ExceptionFrame* frame = c11__at(pkpy_ExceptionFrame, &self->stacktrace, i);
+        pkpy_Str s = pkpy_SourceData__snapshot(frame->src, frame->lineno, frame->cursor, pkpy_Str__data(&frame->name));
+        pkpy_SStream__write_Str(&ss, &s);
+        pkpy_Str__dtor(&s);
+        pkpy_SStream__write_cstr(&ss, "\n");
+    }
+
+    const char* name = pkpy_StrName__rmap(self->type);
+    pkpy_SStream__write_cstr(&ss, name);
+
+    if(self->msg.size > 0){
+        pkpy_SStream__write_cstr(&ss, ": ");
+        pkpy_SStream__write_Str(&ss, &self->msg);
+    }
+    return pkpy_SStream__submit(&ss);
+}

+ 2 - 2
src/interpreter/vm.cpp

@@ -1455,9 +1455,9 @@ void VM::__raise_exc(bool re_raise) {
     int actual_ip = frame->ip();
     if(e._ip_on_error >= 0 && e._code_on_error == (void*)frame->co) actual_ip = e._ip_on_error;
     int current_line = frame->co->lines[actual_ip].lineno;  // current line
-    auto current_f_name = frame->co->name.sv();             // current function name
+    const char* current_f_name = frame->co->name.c_str();   // current function name
     if(frame->_callable == nullptr) current_f_name = "";    // not in a function
-    e.st_push(frame->co->src, current_line, nullptr, current_f_name);
+    e.stpush(frame->co->src, current_line, nullptr, current_f_name);
 
     if(next_ip >= 0) {
         throw InternalException(InternalExceptionType::Handled, next_ip);

+ 0 - 17
src/objects/error.cpp

@@ -1,17 +0,0 @@
-#include "pocketpy/objects/error.hpp"
-
-namespace pkpy {
-Str Exception::summary() const {
-    SStream ss;
-    if(is_re) ss << "Traceback (most recent call last):\n";
-    for(int i = stacktrace.size() - 1; i >= 0; i--) {
-        ss << stacktrace[i].snapshot() << '\n';
-    }
-    if(!msg.empty())
-        ss << type.sv() << ": " << msg;
-    else
-        ss << type.sv();
-    return ss.str();
-}
-
-}  // namespace pkpy

+ 10 - 9
src/pocketpy.cpp

@@ -1539,30 +1539,31 @@ void __init_builtins(VM* _vm) {
     _vm->bind_func(VM::tp_exception, __new__, -1, [](VM* vm, ArgsView args) -> PyVar {
         Type cls = PK_OBJ_GET(Type, args[0]);
         StrName cls_name = _type_name(vm, cls);
-        PyObject* e_obj = vm->heap.gcnew<Exception>(cls, cls_name);
+        PyObject* e_obj = vm->heap.gcnew<Exception>(cls, cls_name.index);
         e_obj->_attr = new NameDict();
-        e_obj->as<Exception>()._self = e_obj;
+        e_obj->as<Exception>().self = e_obj;
         return e_obj;
     });
 
     _vm->bind(_vm->_t(VM::tp_exception), "__init__(self, msg=...)", [](VM* vm, ArgsView args) {
         Exception& self = _CAST(Exception&, args[0]);
-        if(args[1].type == tp_ellipsis) {
-            self.msg = "";
-        } else {
-            self.msg = CAST(Str, args[1]);
+        if(args[1].type != tp_ellipsis) {
+            const char* msg = CAST(Str&, args[1]).c_str();
+            pkpy_Str__dtor(&self.msg);
+            pkpy_Str__ctor(&self.msg, msg);
         }
         return vm->None;
     });
 
     _vm->bind__repr__(VM::tp_exception, [](VM* vm, PyVar _0) -> Str {
         Exception& self = _CAST(Exception&, _0);
-        return _S(_type_name(vm, _0.type), '(', self.msg.escape(), ')');
+        const char* msg_s = pkpy_Str__data(&self.msg);
+        return _S(_type_name(vm, _0.type), '(', Str(msg_s).escape(), ')');
     });
 
     _vm->bind__str__(VM::tp_exception, [](VM* vm, PyVar _0) -> Str {
         Exception& self = _CAST(Exception&, _0);
-        return self.msg;
+        return pkpy_Str__copy(&self.msg);
     });
 
     _vm->register_user_class<RangeIter>(_vm->builtins, "_range_iter");
@@ -1743,7 +1744,7 @@ void VM::__compile_error(Error* err){
         VAR((const char*)err->msg)
     ).get();
     Exception& e = __last_exception->as<Exception>();
-    e.st_push(err->src, err->lineno, err->cursor, "");
+    e.stpush(err->src, err->lineno, err->cursor, "");
     PK_DECREF(err->src);
     std::free(err);
     _error(__last_exception);

+ 1 - 1
src/pocketpy_c.cpp

@@ -43,7 +43,7 @@ static PyVar stack_item(VM* vm, int index) {
     try {                                                                                                              \
         __B                                                                                                            \
     } catch(TopLevelException e) {                                                                                     \
-        vm->__c.error = e.ptr->self();                                                                                 \
+        vm->__c.error = (PyObject*)e.ptr->self;                                                                        \
         return false;                                                                                                  \
     } catch(const std::exception& re) {                                                                                \
         PyObject* e_t = vm->_t(vm->tp_exception);                                                                      \