This commit is contained in:
blueloveTH 2024-08-05 17:06:21 +08:00
parent 90eb50a3a5
commit 0918256c90
3 changed files with 42 additions and 25 deletions

View File

@ -415,8 +415,8 @@ enum py_PredefinedTypes {
tp_function, tp_function,
tp_nativefunc, tp_nativefunc,
tp_boundmethod, tp_boundmethod,
tp_super, // 1 slot + py_Type tp_super, // 1 slot + py_Type
tp_BaseException, tp_BaseException, // 2 slots (arg + inner exc)
tp_Exception, tp_Exception,
tp_bytes, tp_bytes,
tp_mappingproxy, tp_mappingproxy,

View File

@ -2544,9 +2544,9 @@ static Error* compile_try_except(Compiler* self) {
Ctx__emit_(ctx(), OP_PUSH_EXCEPTION, BC_NOARG, BC_KEEPLINE); Ctx__emit_(ctx(), OP_PUSH_EXCEPTION, BC_NOARG, BC_KEEPLINE);
Ctx__emit_store_name(ctx(), name_scope(self), as_name, BC_KEEPLINE); Ctx__emit_store_name(ctx(), name_scope(self), as_name, BC_KEEPLINE);
} }
check(compile_block_body(self, compile_stmt));
// pop the exception // pop the exception
Ctx__emit_(ctx(), OP_POP_EXCEPTION, BC_NOARG, BC_KEEPLINE); Ctx__emit_(ctx(), OP_POP_EXCEPTION, BC_NOARG, BC_KEEPLINE);
check(compile_block_body(self, compile_stmt));
patches[patches_length++] = Ctx__emit_(ctx(), OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE); patches[patches_length++] = Ctx__emit_(ctx(), OP_JUMP_FORWARD, BC_NOARG, BC_KEEPLINE);
Ctx__patch_jump(ctx(), patch); Ctx__patch_jump(ctx(), patch);
} while(curr()->type == TK_EXCEPT); } while(curr()->type == TK_EXCEPT);

View File

@ -52,8 +52,10 @@ static void BaseException__dtor(void* ud) {
static bool _py_BaseException__new__(int argc, py_Ref argv) { 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, 2, sizeof(BaseException));
c11_vector__ctor(&ud->stacktrace, sizeof(BaseExceptionFrame)); c11_vector__ctor(&ud->stacktrace, sizeof(BaseExceptionFrame));
py_setslot(py_retval(), 0, py_NIL);
py_setslot(py_retval(), 1, py_NIL);
ud->lineno_backup = -1; ud->lineno_backup = -1;
ud->code_backup = NULL; ud->code_backup = NULL;
return true; return true;
@ -138,35 +140,46 @@ void py_printexc() {
free(msg); free(msg);
} }
static void c11_sbuf__write_exc(c11_sbuf* self, py_Ref exc){
if(true) { c11_sbuf__write_cstr(self, "Traceback (most recent call last):\n"); }
BaseException* ud = py_touserdata(exc);
for(int i = ud->stacktrace.count - 1; i >= 0; i--) {
BaseExceptionFrame* frame = c11__at(BaseExceptionFrame, &ud->stacktrace, i);
SourceData__snapshot(frame->src,
self,
frame->lineno,
NULL,
frame->name ? frame->name->data : NULL);
c11_sbuf__write_char(self, '\n');
}
const char* name = py_tpname(exc->type);
bool ok = py_str(exc);
if(!ok) c11__abort("py_printexc(): failed to convert exception to string");
const char* message = py_tostr(py_retval());
c11_sbuf__write_cstr(self, name);
c11_sbuf__write_cstr(self, ": ");
c11_sbuf__write_cstr(self, message);
}
char* py_formatexc() { char* py_formatexc() {
VM* vm = pk_current_vm; VM* vm = pk_current_vm;
if(py_isnil(&vm->curr_exception)) return NULL; if(py_isnil(&vm->curr_exception)) return NULL;
c11_sbuf ss; c11_sbuf ss;
c11_sbuf__ctor(&ss); c11_sbuf__ctor(&ss);
if(true) { c11_sbuf__write_cstr(&ss, "Traceback (most recent call last):\n"); } py_Ref inner = py_getslot(&vm->curr_exception, 1);
if(py_isnil(inner)) {
BaseException* ud = py_touserdata(&vm->curr_exception); c11_sbuf__write_exc(&ss, &vm->curr_exception);
} else {
for(int i = ud->stacktrace.count - 1; i >= 0; i--) { c11_sbuf__write_exc(&ss, inner);
BaseExceptionFrame* frame = c11__at(BaseExceptionFrame, &ud->stacktrace, i); c11_sbuf__write_cstr(&ss, "\n\nDuring handling of the above exception, another exception occurred:\n\n");
SourceData__snapshot(frame->src, c11_sbuf__write_exc(&ss, &vm->curr_exception);
&ss,
frame->lineno,
NULL,
frame->name ? frame->name->data : NULL);
c11_sbuf__write_char(&ss, '\n');
} }
const char* name = py_tpname(vm->curr_exception.type);
bool ok = py_str(&vm->curr_exception);
if(!ok) c11__abort("py_printexc(): failed to convert exception to string");
const char* message = py_tostr(py_retval());
c11_sbuf__write_cstr(&ss, name);
c11_sbuf__write_cstr(&ss, ": ");
c11_sbuf__write_cstr(&ss, message);
c11_string* res = c11_sbuf__submit(&ss); c11_string* res = c11_sbuf__submit(&ss);
char* dup = malloc(res->size + 1); char* dup = malloc(res->size + 1);
memcpy(dup, res->data, res->size); memcpy(dup, res->data, res->size);
@ -196,6 +209,10 @@ bool py_exception(py_Type type, const char* fmt, ...) {
bool py_raise(py_Ref exc) { bool py_raise(py_Ref exc) {
assert(py_isinstance(exc, tp_BaseException)); assert(py_isinstance(exc, tp_BaseException));
VM* vm = pk_current_vm; VM* vm = pk_current_vm;
if(!py_isnil(&vm->curr_exception)){
// inner exception
py_setslot(exc, 1, &vm->curr_exception);
}
vm->curr_exception = *exc; vm->curr_exception = *exc;
return false; return false;
} }