mirror of
https://github.com/pocketpy/pocketpy
synced 2025-10-20 03:20:18 +00:00
...
This commit is contained in:
parent
90eb50a3a5
commit
0918256c90
@ -416,7 +416,7 @@ enum py_PredefinedTypes {
|
||||
tp_nativefunc,
|
||||
tp_boundmethod,
|
||||
tp_super, // 1 slot + py_Type
|
||||
tp_BaseException,
|
||||
tp_BaseException, // 2 slots (arg + inner exc)
|
||||
tp_Exception,
|
||||
tp_bytes,
|
||||
tp_mappingproxy,
|
||||
|
@ -2544,9 +2544,9 @@ static Error* compile_try_except(Compiler* self) {
|
||||
Ctx__emit_(ctx(), OP_PUSH_EXCEPTION, BC_NOARG, BC_KEEPLINE);
|
||||
Ctx__emit_store_name(ctx(), name_scope(self), as_name, BC_KEEPLINE);
|
||||
}
|
||||
check(compile_block_body(self, compile_stmt));
|
||||
// pop the exception
|
||||
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);
|
||||
Ctx__patch_jump(ctx(), patch);
|
||||
} while(curr()->type == TK_EXCEPT);
|
||||
|
@ -52,8 +52,10 @@ static void BaseException__dtor(void* ud) {
|
||||
|
||||
static bool _py_BaseException__new__(int argc, py_Ref 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));
|
||||
py_setslot(py_retval(), 0, py_NIL);
|
||||
py_setslot(py_retval(), 1, py_NIL);
|
||||
ud->lineno_backup = -1;
|
||||
ud->code_backup = NULL;
|
||||
return true;
|
||||
@ -138,35 +140,46 @@ void py_printexc() {
|
||||
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() {
|
||||
VM* vm = pk_current_vm;
|
||||
if(py_isnil(&vm->curr_exception)) return NULL;
|
||||
c11_sbuf ss;
|
||||
c11_sbuf__ctor(&ss);
|
||||
|
||||
if(true) { c11_sbuf__write_cstr(&ss, "Traceback (most recent call last):\n"); }
|
||||
|
||||
BaseException* ud = py_touserdata(&vm->curr_exception);
|
||||
|
||||
for(int i = ud->stacktrace.count - 1; i >= 0; i--) {
|
||||
BaseExceptionFrame* frame = c11__at(BaseExceptionFrame, &ud->stacktrace, i);
|
||||
SourceData__snapshot(frame->src,
|
||||
&ss,
|
||||
frame->lineno,
|
||||
NULL,
|
||||
frame->name ? frame->name->data : NULL);
|
||||
c11_sbuf__write_char(&ss, '\n');
|
||||
py_Ref inner = py_getslot(&vm->curr_exception, 1);
|
||||
if(py_isnil(inner)) {
|
||||
c11_sbuf__write_exc(&ss, &vm->curr_exception);
|
||||
} else {
|
||||
c11_sbuf__write_exc(&ss, inner);
|
||||
c11_sbuf__write_cstr(&ss, "\n\nDuring handling of the above exception, another exception occurred:\n\n");
|
||||
c11_sbuf__write_exc(&ss, &vm->curr_exception);
|
||||
}
|
||||
|
||||
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);
|
||||
char* dup = malloc(res->size + 1);
|
||||
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) {
|
||||
assert(py_isinstance(exc, tp_BaseException));
|
||||
VM* vm = pk_current_vm;
|
||||
if(!py_isnil(&vm->curr_exception)){
|
||||
// inner exception
|
||||
py_setslot(exc, 1, &vm->curr_exception);
|
||||
}
|
||||
vm->curr_exception = *exc;
|
||||
return false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user