From 67ae21d18debee6eaccef347d6e9613544cdc08d Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 30 Jul 2024 18:12:22 +0800 Subject: [PATCH] ... --- build.sh | 20 +++++++++----------- include/pocketpy/interpreter/vm.h | 2 ++ include/pocketpy/pocketpy.h | 10 +++++----- src/interpreter/ceval.c | 13 +++++-------- src/interpreter/vm.c | 4 ++-- src/public/modules.c | 22 ++++++++++------------ src/public/py_exception.c | 2 +- src/public/vm.c | 19 ++++++++++++------- 8 files changed, 46 insertions(+), 46 deletions(-) diff --git a/build.sh b/build.sh index d1760346..0fb29e1e 100644 --- a/build.sh +++ b/build.sh @@ -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." diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 0a855eaf..193acfc7 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -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. diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 8ed07d7c..db56bd6a 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -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); diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 76e94a77..ea3a441f 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -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, diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 32933dc1..12050a50 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -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; diff --git a/src/public/modules.c b/src/public/modules.c index d6210e71..f2d54f64 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -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()); // [| ] + bool ok = py_pushmethod(py_name("sort")); // [| list.sort, ] 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, , key] + py_push(py_arg(2)); // [| list.sort, , key, reverse] + ok = py_vectorcall(2, 0); // [| ] + if(!ok) return false; + py_assign(py_retval(), py_peek(-1)); + py_pop(); return true; } diff --git a/src/public/py_exception.c b/src/public/py_exception.c index 31b1446d..96d07f74 100644 --- a/src/public/py_exception.c +++ b/src/public/py_exception.c @@ -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); diff --git a/src/public/vm.c b/src/public/vm.c index 74dd61de..8f67ca91 100644 --- a/src/public/vm.c +++ b/src/public/vm.c @@ -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(); }