This commit is contained in:
blueloveTH 2024-07-30 18:12:22 +08:00
parent db0acc854c
commit 67ae21d18d
8 changed files with 46 additions and 46 deletions

View File

@ -1,9 +1,9 @@
#!/bin/bash
# Check if clang++ is installed
if ! type -P clang++ >/dev/null 2>&1; then
echo "clang++ is required and not installed. Kindly install it."
echo "Run: sudo apt-get install libc++-dev libc++abi-dev clang"
# Check if clang is installed
if ! type -P clang >/dev/null 2>&1; then
echo "clang is required and not installed. Kindly install it."
echo "Run: sudo apt-get install clang"
exit 1
fi
@ -18,13 +18,11 @@ if [ $? -ne 0 ]; then
exit 1
fi
SRC_C=$(find src/ -name "*.c")
SRC_CPP=$(find src/ -name "*.cpp")
SRC="$SRC_C $SRC_CPP"
SRC=$(find src/ -name "*.c")
echo "> Compiling and linking source files... "
FLAGS="-std=c++17 -O1 -stdlib=libc++ -frtti -Wfatal-errors -Iinclude"
FLAGS="-std=c11 -O1 -Wfatal-errors -Iinclude"
if [[ "$OSTYPE" == "darwin"* ]]; then
LIB_EXTENSION=".dylib"
@ -35,12 +33,12 @@ else
LINK_FLAGS="-Wl,-rpath=."
fi
clang++ $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared
clang $FLAGS -o libpocketpy$LIB_EXTENSION $SRC -fPIC -shared
# compile main.cpp and link to libpocketpy.so
echo "> Compiling main.cpp and linking to libpocketpy$LIB_EXTENSION..."
echo "> Compiling main.c and linking to libpocketpy$LIB_EXTENSION..."
clang++ $FLAGS -o main -O1 src2/main.cpp -L. -lpocketpy $LINK_FLAGS
clang $FLAGS -o main -O1 src2/main.c -L. -lpocketpy $LINK_FLAGS
if [ $? -eq 0 ]; then
echo "Build completed. Type \"./main\" to enter REPL."

View File

@ -93,6 +93,8 @@ int pk_arrayequal(py_TValue* lhs, int lhs_length, py_TValue* rhs, int rhs_length
bool pk_arrayiter(py_Ref val);
bool pk_arraycontains(py_Ref self, py_Ref val);
bool pk_pushmethod(py_StackRef self, py_Name name);
/// Assumes [a, b] are on the stack, performs a binary op.
/// The result is stored in `self->last_retval`.
/// The stack remains unchanged.

View File

@ -178,17 +178,12 @@ bool py_deldict(py_Ref self, py_Name name);
py_ObjectRef py_getslot(py_Ref self, int i);
void py_setslot(py_Ref self, int i, py_Ref val);
py_TmpRef py_getupvalue(py_StackRef argv);
void py_setupvalue(py_StackRef argv, py_Ref val);
/// Gets the attribute of the object.
bool py_getattr(py_Ref self, py_Name name);
/// Sets the attribute of the object.
bool py_setattr(py_Ref self, py_Name name, py_Ref val);
/// Deletes the attribute of the object.
bool py_delattr(py_Ref self, py_Name name);
/// Gets the unbound method of the object.
bool py_getunboundmethod(py_Ref self, py_Name name, py_Ref out, py_Ref out_self);
bool py_getitem(py_Ref self, py_Ref key);
bool py_setitem(py_Ref self, py_Ref key, py_Ref val);
@ -231,6 +226,11 @@ void py_pop();
void py_shrink(int n);
/// Get a temporary variable from the stack and returns the reference to it.
py_StackRef py_pushtmp();
/// Gets the unbound method of the object.
/// Assumes the object is located at the top of the stack.
/// If returns true: [self] -> [unbound, self]
/// If returns false: [self] -> [self] (no change)
bool py_pushmethod(py_Name name);
/************* Modules *************/
py_TmpRef py_newmodule(const char* name, const char* package);

View File

@ -251,12 +251,9 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
goto __ERROR;
}
case OP_LOAD_METHOD: {
// [self]
bool ok = py_getunboundmethod(TOP(), byte.arg, TOP(), SP());
if(ok) {
// [unbound, self]
SP()++;
} else {
// [self] -> [unbound, self]
bool ok = py_pushmethod(byte.arg);
if(!ok) {
// fallback to getattr
if(py_getattr(TOP(), byte.arg)) {
py_assign(TOP(), py_retval());
@ -912,8 +909,8 @@ pk_FrameResult pk_VM__run_top_frame(pk_VM* self) {
pk_print_stack(self, frame, (Bytecode){});
py_BaseException__set_lineno(&self->curr_exception, Frame__lineno(frame), frame->co);
__ERROR_RE_RAISE:
printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame));
do {} while(0);
//printf("error.op: %s, line: %d\n", pk_opname(byte.op), Frame__lineno(frame));
int lineno = py_BaseException__get_lineno(&self->curr_exception, frame->co);
py_BaseException__stpush(&self->curr_exception,
frame->co->src,

View File

@ -478,7 +478,7 @@ pk_FrameResult pk_VM__vectorcall(pk_VM* self, uint16_t argc, uint16_t kwargc, bo
}
// handle `__call__` overload
if(py_getunboundmethod(p0, __call__, p0, p0 + 1)) {
if(pk_pushmethod(p0, __call__)) {
// [__call__, self, args..., kwargs...]
return pk_VM__vectorcall(self, argc, kwargc, opcall);
}
@ -557,7 +557,7 @@ void pk_ManagedHeap__mark(pk_ManagedHeap* self) {
}
void pk_print_stack(pk_VM* self, Frame* frame, Bytecode byte) {
// return;
return;
if(frame == NULL) return;
py_TValue* sp = self->stack.sp;

View File

@ -132,19 +132,17 @@ static bool _py_builtins__next(int argc, py_Ref argv) {
static bool _py_builtins__sorted(int argc, py_Ref argv) {
PY_CHECK_ARGC(3);
// convert _0 to list object
if(!py_tpcall(tp_list, 1, argv)) return false;
py_Ref retval = py_pushtmp();
py_Ref sort = py_pushtmp();
py_Ref self = py_pushtmp();
py_Ref key = py_pushtmp();
py_Ref reverse = py_pushtmp();
*self = *retval = *py_retval();
bool ok = py_getunboundmethod(self, py_name("sort"), sort, self);
if(!py_tpcall(tp_list, 1, py_arg(0))) return false;
py_push(py_retval()); // duptop
py_push(py_retval()); // [| <list>]
bool ok = py_pushmethod(py_name("sort")); // [| list.sort, <list>]
if(!ok) return false;
*key = argv[1];
*reverse = argv[2];
if(!py_vectorcall(2, 0)) return false;
*py_retval() = *retval;
py_push(py_arg(1)); // [| list.sort, <list>, key]
py_push(py_arg(2)); // [| list.sort, <list>, key, reverse]
ok = py_vectorcall(2, 0); // [| ]
if(!ok) return false;
py_assign(py_retval(), py_peek(-1));
py_pop();
return true;
}

View File

@ -129,7 +129,7 @@ void py_printexc() {
char* py_formatexc() {
pk_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__ctor(&ss);

View File

@ -230,7 +230,11 @@ bool py_vectorcall(uint16_t argc, uint16_t kwargc) {
py_Ref py_retval() { return &pk_current_vm->last_retval; }
bool py_getunboundmethod(py_Ref self, py_Name name, py_Ref out, py_Ref out_self) {
bool py_pushmethod(py_Name name){
return pk_pushmethod(py_peek(-1), name);
}
bool pk_pushmethod(py_StackRef self, py_Name name) {
// NOTE: `out` and `out_self` may overlap with `self`
py_Type type;
// handle super() proxy
@ -243,22 +247,23 @@ bool py_getunboundmethod(py_Ref self, py_Name name, py_Ref out, py_Ref out_self)
py_Ref cls_var = py_tpfindname(type, name);
if(cls_var != NULL) {
pk_current_vm->stack.sp++;
switch(cls_var->type) {
case tp_function:
case tp_nativefunc: {
py_TValue self_bak = *self;
// `out` may overlap with `self`. If we assign `out`, `self` may be corrupted.
*out = *cls_var;
*out_self = self_bak;
self[0] = *cls_var;
self[1] = self_bak;
break;
}
case tp_staticmethod:
*out = *py_getslot(cls_var, 0);
py_newnil(out_self);
self[0] = *py_getslot(cls_var, 0);
self[1] = *py_NIL;
break;
case tp_classmethod:
*out = *py_getslot(cls_var, 0);
*out_self = c11__getitem(pk_TypeInfo, &pk_current_vm->types, type).self;
self[0] = *py_getslot(cls_var, 0);
self[1] = c11__getitem(pk_TypeInfo, &pk_current_vm->types, type).self;
break;
default: c11__unreachedable();
}