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_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,
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user