This commit is contained in:
blueloveTH 2024-07-09 01:32:14 +08:00
parent 40d6f1a19f
commit 45de08dd39
9 changed files with 112 additions and 24 deletions

View File

@ -51,7 +51,7 @@ typedef struct pk_VM {
void (*_stderr)(const char*, ...); void (*_stderr)(const char*, ...);
py_TValue last_retval; py_TValue last_retval;
bool has_error; py_TValue last_exception;
bool is_stopiteration; bool is_stopiteration;
py_TValue reg[8]; // users' registers py_TValue reg[8]; // users' registers
@ -114,6 +114,8 @@ py_Type pk_function__register();
py_Type pk_nativefunc__register(); py_Type pk_nativefunc__register();
py_Type pk_range__register(); py_Type pk_range__register();
py_Type pk_range_iterator__register(); py_Type pk_range_iterator__register();
py_Type pk_BaseException__register();
py_Type pk_Exception__register();
py_TValue pk_builtins__register(); py_TValue pk_builtins__register();

View File

@ -13,12 +13,12 @@ extern "C" {
// pk_SourceData_ src; // pk_SourceData_ src;
// int lineno; // int lineno;
// const char* cursor; // const char* cursor;
// py_Str name; // c11_string* name;
// } pkpy_ExceptionFrame; // } pkpy_ExceptionFrame;
// typedef struct pkpy_Exception { // typedef struct pkpy_Exception {
// py_Name type; // py_Name type;
// py_Str msg; // c11_string* msg;
// bool is_re; // bool is_re;
// int _ip_on_error; // int _ip_on_error;

View File

@ -409,6 +409,7 @@ enum py_PredefinedTypes {
tp_nativefunc, tp_nativefunc,
tp_bound_method, tp_bound_method,
tp_super, // 1 slot + py_Type tp_super, // 1 slot + py_Type
tp_base_exception,
tp_exception, tp_exception,
tp_bytes, tp_bytes,
tp_mappingproxy, tp_mappingproxy,

View File

@ -83,7 +83,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
__NEXT_STEP: __NEXT_STEP:
byte = *frame->ip; byte = *frame->ip;
#if 0 #if 1
c11_sbuf buf; c11_sbuf buf;
c11_sbuf__ctor(&buf); c11_sbuf__ctor(&buf);
for(py_Ref p = self->stack.begin; p != SP(); p++) { for(py_Ref p = self->stack.begin; p != SP(); p++) {
@ -777,7 +777,6 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
// 1. Exception can be handled inside the current frame // 1. Exception can be handled inside the current frame
// 2. Exception need to be propagated to the upper frame // 2. Exception need to be propagated to the upper frame
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));
assert(false);
return RES_ERROR; return RES_ERROR;
} }

View File

@ -71,7 +71,7 @@ void pk_VM__ctor(pk_VM* self) {
self->_stderr = pk_default_stderr; self->_stderr = pk_default_stderr;
self->last_retval = PY_NIL; self->last_retval = PY_NIL;
self->has_error = false; self->last_exception = PY_NIL;
self->is_stopiteration = false; self->is_stopiteration = false;
self->__curr_class = PY_NIL; self->__curr_class = PY_NIL;
@ -112,7 +112,8 @@ void pk_VM__ctor(pk_VM* self) {
validate(tp_bound_method, pk_VM__new_type(self, "bound_method", tp_object, NULL, false)); validate(tp_bound_method, pk_VM__new_type(self, "bound_method", tp_object, NULL, false));
validate(tp_super, pk_VM__new_type(self, "super", tp_object, NULL, false)); validate(tp_super, pk_VM__new_type(self, "super", tp_object, NULL, false));
validate(tp_exception, pk_VM__new_type(self, "Exception", tp_object, NULL, true)); validate(tp_base_exception, pk_BaseException__register());
validate(tp_exception, pk_Exception__register());
validate(tp_bytes, pk_bytes__register()); validate(tp_bytes, pk_bytes__register());
validate(tp_mappingproxy, pk_VM__new_type(self, "mappingproxy", tp_object, NULL, false)); validate(tp_mappingproxy, pk_VM__new_type(self, "mappingproxy", tp_object, NULL, false));
@ -148,6 +149,7 @@ void pk_VM__ctor(pk_VM* self) {
tp_bytes, tp_bytes,
tp_dict, tp_dict,
tp_property, tp_property,
tp_base_exception,
tp_exception, tp_exception,
tp_stop_iteration, tp_stop_iteration,
tp_syntax_error}; tp_syntax_error};

View File

@ -4,24 +4,25 @@
#include <stdarg.h> #include <stdarg.h>
void py_printexc(){ void py_printexc() {
pk_VM* vm = pk_current_vm; pk_VM* vm = pk_current_vm;
if(vm->has_error){ if(py_isnil(&vm->last_exception)) {
assert(vm->last_retval.type == tp_exception);
}else{
vm->_stdout("NoneType: None\n"); vm->_stdout("NoneType: None\n");
} else {
const char* name = py_tpname(vm->last_exception.type);
bool ok = py_str(&vm->last_exception);
if(!ok) abort();
const char* message = py_tostr(py_retval());
vm->_stdout("%s: %s\n", name, message);
} }
} }
void py_formatexc(char* out) {}
void py_formatexc(char *out){ bool py_exception(const char* name, const char* fmt, ...) {
}
bool py_exception(const char* name, const char* fmt, ...){
pk_VM* vm = pk_current_vm; pk_VM* vm = pk_current_vm;
assert(!vm->has_error); // an error is already set // an error is already set
vm->has_error = true; assert(py_isnil(&vm->last_exception));
c11_sbuf buf; c11_sbuf buf;
c11_sbuf__ctor(&buf); c11_sbuf__ctor(&buf);
@ -31,8 +32,14 @@ bool py_exception(const char* name, const char* fmt, ...){
va_end(args); va_end(args);
c11_string* res = c11_sbuf__submit(&buf); c11_string* res = c11_sbuf__submit(&buf);
// vm->last_retval = py_newexception(name, res->data); py_Ref message = py_pushtmp();
vm->_stderr("%s: %s\n", name, res->data); py_newstrn(message, res->data, res->size);
c11_string__delete(res); c11_string__delete(res);
py_pop();
bool ok = py_tpcall(tp_exception, 1, message);
if(!ok) abort();
vm->last_exception = *py_retval();
return false; return false;
} }

81
src/public/py_exception.c Normal file
View File

@ -0,0 +1,81 @@
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/object.h"
#include "pocketpy/interpreter/vm.h"
#include "pocketpy/common/sstream.h"
typedef struct BaseExceptionFrame {
pk_SourceData_ src;
int lineno;
c11_string* name;
} BaseExceptionFrame;
typedef struct BaseException {
int ip_backup;
CodeObject* code_backup;
c11_vector /*T=BaseExceptionFrame*/ stacktrace;
} BaseException;
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));
ud->ip_backup = -1;
ud->code_backup = NULL;
return true;
}
static bool _py_BaseException__init__(int argc, py_Ref argv) {
if(argc == 1 + 0) { return true; }
if(argc == 1 + 1) {
py_setslot(py_arg(0), 0, py_arg(1));
return true;
}
return TypeError("__init__() takes at most 2 arguments but %d were given", argc);
}
static bool _py_BaseException__repr__(int argc, py_Ref argv) {
c11_sbuf ss;
c11_sbuf__ctor(&ss);
pk_sprintf(&ss, "%t(", argv->type);
py_Ref arg = py_getslot(argv, 0);
if(!py_isnil(arg)) {
if(!py_repr(arg)) return false;
c11_sbuf__write_sv(&ss, py_tosv(py_retval()));
}
c11_sbuf__write_char(&ss, ')');
c11_string* res = c11_sbuf__submit(&ss);
py_newstrn(py_retval(), res->data, res->size);
c11_string__delete(res);
return true;
}
static bool _py_BaseException__str__(int argc, py_Ref argv) {
c11_sbuf ss;
c11_sbuf__ctor(&ss);
py_Ref arg = py_getslot(argv, 0);
if(!py_isnil(arg)) {
if(!py_str(arg)) return false;
c11_sbuf__write_sv(&ss, py_tosv(py_retval()));
}
c11_string* res = c11_sbuf__submit(&ss);
py_newstrn(py_retval(), res->data, res->size);
c11_string__delete(res);
return true;
}
py_Type pk_BaseException__register() {
pk_VM* vm = pk_current_vm;
py_Type type = pk_VM__new_type(vm, "BaseException", tp_object, NULL, true);
py_bindmagic(type, __new__, _py_BaseException__new__);
py_bindmagic(type, __init__, _py_BaseException__init__);
py_bindmagic(type, __repr__, _py_BaseException__repr__);
py_bindmagic(type, __str__, _py_BaseException__str__);
return type;
}
py_Type pk_Exception__register() {
pk_VM* vm = pk_current_vm;
py_Type type = pk_VM__new_type(vm, "Exception", tp_base_exception, NULL, true);
return type;
}

View File

@ -1,4 +0,0 @@
def f(a, b):
return a+b
assert f(1, 2) == 3