mirror of
https://github.com/pocketpy/pocketpy
synced 2025-12-07 02:30:17 +00:00
move error.h
This commit is contained in:
parent
31bf7f45c4
commit
3a257aefb1
@ -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);
|
||||
|
||||
@ -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
include/pocketpy/objects/error.h
Normal file
39
include/pocketpy/objects/error.h
Normal 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
|
||||
@ -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;
|
||||
struct Exception: pkpy_Exception{
|
||||
PK_ALWAYS_PASS_BY_POINTER(Exception)
|
||||
|
||||
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;
|
||||
Exception(uint16_t type){
|
||||
pkpy_Exception__ctor(this, type);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void st_push(Args&&... args) {
|
||||
if(stacktrace.size() >= 7) return;
|
||||
stacktrace.emplace_back(std::forward<Args>(args)...);
|
||||
~Exception(){
|
||||
pkpy_Exception__dtor(this);
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
@ -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
src/error.c
Normal file
59
src/error.c
Normal 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);
|
||||
}
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
@ -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);
|
||||
|
||||
@ -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); \
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user