Compare commits

...

3 Commits

Author SHA1 Message Date
blueloveTH
a8dfbc9147 ... 2024-07-25 20:46:41 +08:00
blueloveTH
3ea3cf7366 ... 2024-07-25 19:55:19 +08:00
blueloveTH
b6eeaa8cbc ... 2024-07-25 19:12:51 +08:00
12 changed files with 56 additions and 33 deletions

View File

@ -27,9 +27,10 @@ extern "C" {
#define c11__unreachedable() __builtin_unreachable()
#endif
#define PK_FATAL_ERROR(...) \
#define c11__abort(...) \
do { \
fprintf(stderr, __VA_ARGS__); \
putchar('\n'); \
abort(); \
} while(0)

View File

@ -255,7 +255,7 @@ int c11__u8_header(unsigned char c, bool suppress) {
if((c & 0b11111000) == 0b11110000) return 4;
if((c & 0b11111100) == 0b11111000) return 5;
if((c & 0b11111110) == 0b11111100) return 6;
if(!suppress) PK_FATAL_ERROR("invalid utf8 char\n");
if(!suppress) c11__abort("invalid utf8 char");
return 0;
}

View File

@ -38,7 +38,7 @@ py_Name py_namev(c11_sv name) {
uint16_t index = c11_smallmap_s2n__get(&_interned, name, 0);
if(index != 0) return index;
// generate new index
if(_interned.count > 65530) PK_FATAL_ERROR("py_Name index overflow\n");
if(_interned.count > 65530) c11__abort("py_Name index overflow");
// NOTE: we must allocate the string in the heap so iterators are not invalidated
char* p = malloc(name.size + 1);
memcpy(p, name.data, name.size);

View File

@ -1484,8 +1484,7 @@ static NameScope name_scope(Compiler* self) {
}
Error* SyntaxError(const char* fmt, ...) {
printf("%s\n", fmt);
abort();
c11__abort("%s", fmt);
return NULL;
}

View File

@ -82,20 +82,6 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
while(true) {
Bytecode byte;
__NEXT_FRAME:
// if(__internal_exception.type == InternalExceptionType::Null) {
// // None
// frame->_ip++;
// } else if(__internal_exception.type == InternalExceptionType::Handled) {
// // HandledException + continue
// frame->_ip = c11__at(Bytecode, &frame->co->codes, __internal_exception.arg);
// __internal_exception = {};
// } else {
// // UnhandledException + continue (need_raise = true)
// // ToBeRaisedException + continue (need_raise = true)
// __internal_exception = {};
// __raise_exc(); // no return
// }
frame->ip++;
__NEXT_STEP:
@ -859,8 +845,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
}
case OP_EXCEPTION_MATCH: {
if(!py_checktype(TOP(), tp_type)) goto __ERROR;
bool ok = py_isinstance(TOP(), py_totype(&self->curr_exception));
POP();
bool ok = py_isinstance(&self->curr_exception, py_totype(TOP()));
py_newbool(TOP(), ok);
DISPATCH();
}
@ -888,7 +873,7 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
goto __ERROR;
}
case OP_RE_RAISE: {
py_raise(&self->curr_exception);
assert(self->curr_exception.type);
goto __ERROR_RE_RAISE;
}
case OP_PUSH_EXCEPTION: {
@ -940,7 +925,14 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
DISPATCH_JUMP_ABSOLUTE(target);
} else {
// 2. Exception need to be propagated to the upper frame
return RES_ERROR;
bool is_base_frame_to_be_popped = frame == base_frame;
pk_VM__pop_frame(self);
if(self->top_frame == NULL || is_base_frame_to_be_popped) {
// propagate to the top level
return RES_ERROR;
}
frame = self->top_frame;
goto __ERROR;
}
}

View File

@ -176,13 +176,14 @@ void pk_VM__ctor(pk_VM* self) {
"AttributeError",
"ImportError",
"AssertionError",
// "KeyError",
"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));
it++;
}
py_TValue tmp;
@ -277,7 +278,9 @@ bool pk__parse_int_slice(py_Ref slice, int length, int* start, int* stop, int* s
bool pk__normalize_index(int* index, int length) {
if(*index < 0) *index += length;
if(*index < 0 || *index >= length) { return IndexError("index out of range"); }
if(*index < 0 || *index >= length) {
return IndexError("%d not in [0, %d)", *index, length);
}
return true;
}
@ -379,7 +382,6 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
#if 0
// handle boundmethod, do a patch
if(p0->type == tp_boundmethod) {
assert(false);
assert(py_isnil(p0 + 1)); // self must be NULL
// BoundMethod& bm = PK_OBJ_GET(BoundMethod, callable);
// callable = bm.func; // get unbound method

View File

@ -4,7 +4,7 @@
void Bytecode__set_signed_arg(Bytecode* self, int arg) {
if(arg < INT16_MIN || arg > INT16_MAX) {
PK_FATAL_ERROR("set_signed_arg: %d is out of range", arg);
c11__abort("set_signed_arg: %d is out of range", arg);
}
self->arg = (int16_t)arg;
}

View File

@ -1,3 +1,4 @@
#include "pocketpy/common/utils.h"
#include "pocketpy/objects/base.h"
#include "pocketpy/pocketpy.h"
#include "pocketpy/common/sstream.h"
@ -17,7 +18,7 @@ void py_printexc() {
} else {
const char* name = py_tpname(vm->curr_exception.type);
bool ok = py_str(&vm->curr_exception);
if(!ok) abort();
if(!ok) c11__abort("py_printexc(): failed to convert exception to string");
const char* message = py_tostr(py_retval());
vm->_stdout("%s: %s\n", name, message);
}
@ -43,8 +44,11 @@ bool py_exception(const char* name, const char* fmt, ...) {
py_Ref message = py_pushtmp();
py_newstrn(message, res->data, res->size);
c11_string__delete(res);
bool ok = py_tpcall(tp_Exception, 1, message);
if(!ok) abort();
py_Ref exc_type = py_getdict(&pk_current_vm->builtins, py_name(name));
if(exc_type == NULL) c11__abort("py_exception(): '%s' not found", name);
bool ok = py_call(exc_type, 1, message);
if(!ok) c11__abort("py_exception(): failed to create exception object");
py_pop();
return py_raise(py_retval());

View File

@ -45,7 +45,7 @@ py_Ref py_newmodule(const char* name, const char* package) {
// we do not allow override in order to avoid memory leak
// it is because Module objects are not garbage collected
bool exists = pk_NameDict__contains(&pk_current_vm->modules, py_name(name));
if(exists) abort();
if(exists) c11__abort("module '%s' already exists", name);
pk_NameDict__set(&pk_current_vm->modules, py_name(name), *r0);
py_shrink(2);
@ -199,6 +199,11 @@ static bool _py_builtins__print(int argc, py_Ref argv) {
return true;
}
static bool _py_NoneType__repr__(int argc, py_Ref argv) {
py_newstr(py_retval(), "None");
return true;
}
py_TValue pk_builtins__register() {
py_Ref builtins = py_newmodule("builtins", NULL);
py_bindnativefunc(builtins, "repr", _py_builtins__repr);
@ -214,6 +219,9 @@ py_TValue pk_builtins__register() {
py_bind(builtins, "print(*args, sep=' ', end='\\n')", _py_builtins__print);
py_bind(builtins, "sorted(iterable, key=None, reverse=False)", _py_builtins__sorted);
// None __repr__
py_bindmagic(tp_NoneType, __repr__, _py_NoneType__repr__);
return *builtins;
}

View File

@ -57,6 +57,13 @@ static bool _py_type__repr__(int argc, py_Ref argv) {
return true;
}
static bool _py_type__new__(int argc, py_Ref argv){
PY_CHECK_ARGC(2);
py_Type type = py_typeof(py_arg(1));
py_assign(py_retval(), py_tpobject(type));
return true;
}
void pk_object__register() {
// use staticmethod
py_bindmagic(tp_object, __new__, _py_object__new__);
@ -68,4 +75,5 @@ void pk_object__register() {
// type patch...
py_bindmagic(tp_type, __repr__, _py_type__repr__);
py_bindmagic(tp_type, __new__, _py_type__new__);
}

View File

@ -73,8 +73,8 @@ void py_bind(py_Ref obj, const char* sig, py_CFunction f) {
CodeObject code;
pk_SourceData_ source = pk_SourceData__rcnew(buffer, "<bind>", EXEC_MODE, false);
Error* err = pk_compile(source, &code);
if(err) abort();
if(code.func_decls.count != 1) abort();
if(err) c11__abort("py_bind(): failed to compile signature '%s'", sig);
if(code.func_decls.count != 1) c11__abort("py_bind(): invalid signature '%s'", sig);
FuncDecl_ decl = c11__getitem(FuncDecl_, &code.func_decls, 0);
// construct the function
Function* ud = py_newobject(&tmp, tp_function, 0, sizeof(Function));

View File

@ -1,3 +1,12 @@
def f():
raise IndexError
try:
f()
exit(1)
except IndexError:
pass
try:
assert False
exit(1)