mirror of
https://github.com/pocketpy/pocketpy
synced 2025-12-07 18:50:19 +00:00
move error.h
This commit is contained in:
parent
31bf7f45c4
commit
3a257aefb1
@ -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);
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
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
|
#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) :
|
~Exception(){
|
||||||
src(src), lineno(lineno), cursor(cursor), name(name) {
|
pkpy_Exception__dtor(this);
|
||||||
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() {
|
void stpush(pkpy_SourceData_ src, int lineno, const char* cursor, const char* name){
|
||||||
if(src) PK_DECREF(src);
|
pkpy_Exception__stpush(this, src, lineno, cursor, name);
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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>
|
Str summary(){
|
||||||
void st_push(Args&&... args) {
|
return pkpy_Exception__summary(this);
|
||||||
if(stacktrace.size() >= 7) return;
|
|
||||||
stacktrace.emplace_back(std::forward<Args>(args)...);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Str summary() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TopLevelException : std::exception {
|
struct TopLevelException : std::exception {
|
||||||
|
|||||||
@ -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
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();
|
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);
|
||||||
|
|||||||
@ -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 {
|
_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);
|
||||||
|
|||||||
@ -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); \
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user