This commit is contained in:
blueloveTH 2024-07-25 16:46:27 +08:00
parent f2363a8657
commit 3e7ca3cddd
6 changed files with 57 additions and 25 deletions

View File

@ -20,7 +20,8 @@ struct Error{
int64_t userdata; int64_t userdata;
}; };
void py_BaseException__record(py_Ref, const Bytecode* ip, const CodeObject* code); void py_BaseException__set_lineno(py_Ref, int lineno, const CodeObject* code);
int py_BaseException__get_lineno(py_Ref, const CodeObject* code);
void py_BaseException__stpush(py_Ref, pk_SourceData_ src, int lineno, const char* func_name); void py_BaseException__stpush(py_Ref, pk_SourceData_ src, int lineno, const char* func_name);
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -7,6 +7,7 @@
#include "pocketpy/objects/codeobject.h" #include "pocketpy/objects/codeobject.h"
#include "pocketpy/pocketpy.h" #include "pocketpy/pocketpy.h"
#include "pocketpy/objects/error.h" #include "pocketpy/objects/error.h"
#include <stdbool.h>
static bool stack_unpack_sequence(pk_VM* self, uint16_t arg); static bool stack_unpack_sequence(pk_VM* self, uint16_t arg);
static bool format_object(py_Ref obj, c11_sv spec); static bool format_object(py_Ref obj, c11_sv spec);
@ -888,7 +889,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
} }
case OP_RE_RAISE: { case OP_RE_RAISE: {
py_raise(&self->curr_exception); py_raise(&self->curr_exception);
goto __ERROR; goto __ERROR_RE_RAISE;
} }
case OP_PUSH_EXCEPTION: { case OP_PUSH_EXCEPTION: {
assert(self->curr_exception.type); assert(self->curr_exception.type);
@ -922,16 +923,16 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
c11__unreachedable(); c11__unreachedable();
__ERROR: __ERROR:
pk_print_stack(self, frame, (Bytecode){OP_NO_OP, 0});
py_BaseException__set_lineno(&self->curr_exception, Frame__lineno(frame), frame->co);
__ERROR_RE_RAISE:
printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame)); printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame));
py_BaseException__record(&self->curr_exception, frame->ip, frame->co); int lineno = py_BaseException__get_lineno(&self->curr_exception, frame->co);
// TODO: lineno bug on re-raise py_BaseException__stpush(&self->curr_exception,
int lineno = Frame__lineno(frame);
py_BaseException__stpush(
&self->curr_exception,
frame->co->src, frame->co->src,
lineno, lineno < 0 ? Frame__lineno(frame) : lineno,
frame->function ? frame->co->name->data : NULL frame->function ? frame->co->name->data : NULL);
);
int target = Frame__prepare_jump_exception_handler(frame, &self->stack); int target = Frame__prepare_jump_exception_handler(frame, &self->stack);
if(target >= 0) { if(target >= 0) {

View File

@ -71,10 +71,8 @@ int Frame__prepare_jump_exception_handler(Frame* self, ValueStack* _s) {
iblock = block->parent; iblock = block->parent;
} }
if(iblock < 0) return -1; if(iblock < 0) return -1;
py_TValue obj = *--_s->sp; // pop exception object
UnwindTarget* uw = Frame__find_unwind_target(self, iblock); UnwindTarget* uw = Frame__find_unwind_target(self, iblock);
_s->sp = (self->locals + uw->offset); // unwind the stack _s->sp = (self->locals + uw->offset); // unwind the stack
*(_s->sp++) = obj; // push it back
return c11__at(CodeBlock, &self->co->blocks, iblock)->end; return c11__at(CodeBlock, &self->co->blocks, iblock)->end;
} }

View File

@ -31,7 +31,7 @@ static void pk_TypeInfo__ctor(pk_TypeInfo* self,
py_Name name, py_Name name,
py_Type index, py_Type index,
py_Type base, py_Type base,
const py_TValue* module) { py_TValue module) {
memset(self, 0, sizeof(pk_TypeInfo)); memset(self, 0, sizeof(pk_TypeInfo));
self->name = name; self->name = name;
@ -47,7 +47,7 @@ static void pk_TypeInfo__ctor(pk_TypeInfo* self,
._obj = typeobj, ._obj = typeobj,
}; };
self->module = module ? *module : *py_NIL; self->module = module;
c11_vector__ctor(&self->annotated_fields, sizeof(py_Name)); c11_vector__ctor(&self->annotated_fields, sizeof(py_Name));
} }
@ -161,6 +161,30 @@ void pk_VM__ctor(pk_VM* self) {
py_setdict(&self->builtins, ti->name, py_tpobject(t)); py_setdict(&self->builtins, ti->name, py_tpobject(t));
} }
// inject some builtin expections
const char** builtin_exceptions = (const char*[]){
"StackOverflowError",
"IOError",
"NotImplementedError",
"TypeError",
"IndexError",
"ValueError",
"RuntimeError",
"ZeroDivisionError",
"NameError",
"UnboundLocalError",
"AttributeError",
"ImportError",
"AssertionError",
// "KeyError",
NULL, // sentinel
};
const char** it = builtin_exceptions;
while(*it){
py_Type type = pk_newtype(*it, tp_Exception, &self->builtins, NULL, false, true);
py_setdict(&self->builtins, py_name(*it), py_tpobject(type));
}
py_TValue tmp; py_TValue tmp;
py_newnotimplemented(&tmp); py_newnotimplemented(&tmp);
py_setdict(&self->builtins, py_name("NotImplemented"), &tmp); py_setdict(&self->builtins, py_name("NotImplemented"), &tmp);
@ -266,7 +290,7 @@ py_Type pk_newtype(const char* name,
c11_vector* types = &pk_current_vm->types; c11_vector* types = &pk_current_vm->types;
py_Type index = types->count; py_Type index = types->count;
pk_TypeInfo* ti = c11_vector__emplace(types); pk_TypeInfo* ti = c11_vector__emplace(types);
pk_TypeInfo__ctor(ti, py_name(name), index, base, module); pk_TypeInfo__ctor(ti, py_name(name), index, base, module ? *module : *py_NIL);
ti->dtor = dtor; ti->dtor = dtor;
ti->is_python = is_python; ti->is_python = is_python;
ti->is_sealed = is_sealed; ti->is_sealed = is_sealed;

View File

@ -14,17 +14,23 @@ typedef struct BaseExceptionFrame {
} BaseExceptionFrame; } BaseExceptionFrame;
typedef struct BaseException { typedef struct BaseException {
const Bytecode* ip_backup; int lineno_backup;
const CodeObject* code_backup; const CodeObject* code_backup;
c11_vector /*T=BaseExceptionFrame*/ stacktrace; c11_vector /*T=BaseExceptionFrame*/ stacktrace;
} BaseException; } BaseException;
void py_BaseException__record(py_Ref self, const Bytecode* ip, const CodeObject* code) { void py_BaseException__set_lineno(py_Ref self, int lineno, const CodeObject* code){
BaseException* ud = py_touserdata(self); BaseException* ud = py_touserdata(self);
ud->ip_backup = ip; ud->lineno_backup = lineno;
ud->code_backup = code; ud->code_backup = code;
} }
int py_BaseException__get_lineno(py_Ref self, const CodeObject* code){
BaseException* ud = py_touserdata(self);
if(code != ud->code_backup) return -1;
return ud->lineno_backup;
}
void py_BaseException__stpush(py_Ref self, pk_SourceData_ src, int lineno, const char *func_name){ void py_BaseException__stpush(py_Ref self, pk_SourceData_ src, int lineno, const char *func_name){
BaseException* ud = py_touserdata(self); BaseException* ud = py_touserdata(self);
if(ud->stacktrace.count >= 7) return; if(ud->stacktrace.count >= 7) return;
@ -48,7 +54,7 @@ static bool _py_BaseException__new__(int argc, py_Ref argv) {
py_Type cls = py_totype(argv); py_Type cls = py_totype(argv);
BaseException* ud = py_newobject(py_retval(), cls, 1, sizeof(BaseException)); BaseException* ud = py_newobject(py_retval(), cls, 1, sizeof(BaseException));
c11_vector__ctor(&ud->stacktrace, sizeof(BaseExceptionFrame)); c11_vector__ctor(&ud->stacktrace, sizeof(BaseExceptionFrame));
ud->ip_backup = NULL; ud->lineno_backup = -1;
ud->code_backup = NULL; ud->code_backup = NULL;
return true; return true;
} }

View File

@ -1,14 +1,14 @@
try:
raise 1
except TypeError:
pass
try: try:
assert False assert False
exit(1) exit(1)
except AssertionError: except AssertionError:
pass pass
try:
raise 1
except TypeError:
pass
try: try:
for i in range(5): for i in range(5):
raise KeyError(i) raise KeyError(i)
@ -134,6 +134,7 @@ except SyntaxError as e:
ok = True ok = True
assert ok assert ok
"""
# finally, only # finally, only
def finally_only(): def finally_only():
try: try:
@ -195,3 +196,4 @@ except KeyError:
exit(0) exit(0)
exit(1) exit(1)
"""