move error.h

This commit is contained in:
blueloveTH 2024-06-17 01:19:41 +08:00
parent 31bf7f45c4
commit 3a257aefb1
10 changed files with 129 additions and 87 deletions

View File

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

View File

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

View File

@ -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

View File

@ -1,7 +1,9 @@
#pragma once #pragma once
#include "pocketpy/common/str.hpp" #include "pocketpy/common/str.hpp"
#include "pocketpy/common/traits.hpp"
#include "pocketpy/objects/sourcedata.h" #include "pocketpy/objects/sourcedata.h"
#include "pocketpy/objects/error.h"
namespace pkpy { namespace pkpy {
@ -22,62 +24,24 @@ struct InternalException final {
InternalException(InternalExceptionType type, int arg = -1) : type(type), arg(arg) {} InternalException(InternalExceptionType type, int arg = -1) : type(type), arg(arg) {}
}; };
struct Exception { struct Exception: pkpy_Exception{
StrName type; PK_ALWAYS_PASS_BY_POINTER(Exception)
Str msg;
bool is_re;
int _ip_on_error; Exception(uint16_t type){
void* _code_on_error; pkpy_Exception__ctor(this, type);
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;
} }
template <typename... Args> ~Exception(){
void st_push(Args&&... args) { pkpy_Exception__dtor(this);
if(stacktrace.size() >= 7) return;
stacktrace.emplace_back(std::forward<Args>(args)...);
} }
Str summary() const; void stpush(pkpy_SourceData_ src, int lineno, const char* cursor, const char* name){
pkpy_Exception__stpush(this, src, lineno, cursor, name);
}
Str summary(){
return pkpy_Exception__summary(this);
}
}; };
struct TopLevelException : std::exception { struct TopLevelException : std::exception {

View File

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

59
src/error.c Normal file
View File

@ -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);
}

View File

@ -1455,9 +1455,9 @@ void VM::__raise_exc(bool re_raise) {
int actual_ip = frame->ip(); int actual_ip = frame->ip();
if(e._ip_on_error >= 0 && e._code_on_error == (void*)frame->co) actual_ip = e._ip_on_error; 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 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 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) { if(next_ip >= 0) {
throw InternalException(InternalExceptionType::Handled, next_ip); throw InternalException(InternalExceptionType::Handled, next_ip);

View File

@ -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

View File

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

View File

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