diff --git a/build_g.sh b/build_g.sh index b0048cd5..b668a308 100644 --- a/build_g.sh +++ b/build_g.sh @@ -2,19 +2,10 @@ set -e python prebuild.py -SRC_C=$(find src/ -name "*.c") -SRC_CPP=$(find src/ -name "*.cpp") +SRC=$(find src/ -name "*.c") -COMMON_FLAGS="-Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" # -fsanitize=address,leak,undefined" - -FLAGS_C="-std=c11 $COMMON_FLAGS" -FLAGS_CPP="-std=c++17 -stdlib=libc++ -frtti $COMMON_FLAGS" +FLAGS="-std=c11 -Iinclude -O0 -Wfatal-errors -g -DDEBUG -DPK_ENABLE_OS=1" # -fsanitize=address,leak,undefined" echo "Compiling C files..." -clang $FLAGS_C -c $SRC_C -ar rcs libpocketpy_c.a *.o -rm *.o +clang $FLAGS $SRC src2/main.c -o main -echo "Compiling C++ files..." -clang++ $FLAGS_CPP -o main src2/main.cpp $SRC_CPP libpocketpy_c.a -rm libpocketpy_c.a diff --git a/include/pocketpy/interpreter/gc.h b/include/pocketpy/interpreter/gc.h index 6cc92f2e..c0d25542 100644 --- a/include/pocketpy/interpreter/gc.h +++ b/include/pocketpy/interpreter/gc.h @@ -1,5 +1,4 @@ #include "pocketpy/objects/object.h" -#include "pocketpy/objects/public.h" #include "pocketpy/common/config.h" #ifdef __cplusplus diff --git a/include/pocketpy/objects/error.h b/include/pocketpy/objects/error.h index 946ffd09..16380727 100644 --- a/include/pocketpy/objects/error.h +++ b/include/pocketpy/objects/error.h @@ -17,7 +17,7 @@ typedef struct pkpy_ExceptionFrame { } pkpy_ExceptionFrame; typedef struct pkpy_Exception { - pk_StrName type; + StrName type; pkpy_Str msg; bool is_re; @@ -29,7 +29,7 @@ typedef struct pkpy_Exception { c11_vector/*T=pkpy_ExceptionFrame*/ stacktrace; } pkpy_Exception; -void pkpy_Exception__ctor(pkpy_Exception* self, pk_StrName type); +void pkpy_Exception__ctor(pkpy_Exception* self, StrName type); void pkpy_Exception__dtor(pkpy_Exception* self); void pkpy_Exception__stpush(pkpy_Exception* self, pkpy_SourceData_ src, int lineno, const char* cursor, const char* name); pkpy_Str pkpy_Exception__summary(pkpy_Exception* self); diff --git a/include/pocketpy/objects/object.h b/include/pocketpy/objects/object.h index a6e2faab..afdafa6b 100644 --- a/include/pocketpy/objects/object.h +++ b/include/pocketpy/objects/object.h @@ -32,7 +32,7 @@ PK_INLINE PyVar PyVar__fromobj(PyObject* obj){ PyVar retval = { .type = obj->type, .is_ptr = true, - ._obj = obj; + ._obj = obj }; return retval; } diff --git a/src/error.c b/src/error.c index 89fba2ae..507edf42 100644 --- a/src/error.c +++ b/src/error.c @@ -2,7 +2,7 @@ #include "pocketpy/common/strname.h" #include "pocketpy/common/sstream.h" -void pkpy_Exception__ctor(pkpy_Exception* self, pk_StrName type){ +void pkpy_Exception__ctor(pkpy_Exception* self, StrName type){ self->type = type; self->is_re = true; self->_ip_on_error = -1; diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index aeb2f554..7aee5a42 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -1,1151 +1,1151 @@ -#include "pocketpy/interpreter/ceval.hpp" -#include "pocketpy/objects/base.h" +// #include "pocketpy/interpreter/ceval.h" +// #include "pocketpy/objects/base.h" -namespace pkpy { +// namespace pkpy { -#define PREDICT_INT_OP(op) \ - if(is_int(_0) && is_int(_1)) { \ - TOP() = VAR(_0._i64 op _1._i64); \ - DISPATCH() \ - } +// #define PREDICT_INT_OP(op) \ +// if(is_int(_0) && is_int(_1)) { \ +// TOP() = VAR(_0._i64 op _1._i64); \ +// DISPATCH() \ +// } -#define PREDICT_INT_DIV_OP(op) \ - if(is_int(_0) && is_int(_1)) { \ - i64 divisor = _1._i64; \ - if(divisor == 0) ZeroDivisionError(); \ - TOP() = VAR(_0._i64 op divisor); \ - DISPATCH() \ - } +// #define PREDICT_INT_DIV_OP(op) \ +// if(is_int(_0) && is_int(_1)) { \ +// i64 divisor = _1._i64; \ +// if(divisor == 0) ZeroDivisionError(); \ +// TOP() = VAR(_0._i64 op divisor); \ +// DISPATCH() \ +// } -#define BINARY_F_COMPARE(func, op, rfunc) \ - PyVar ret; \ - const PyTypeInfo* _ti = _tp_info(_0); \ - if(_ti->m##func) { \ - ret = _ti->m##func(this, _0, _1); \ - } else { \ - PyVar self; \ - PyVar _2 = get_unbound_method(_0, func, &self, false); \ - if(_2.type) \ - ret = call_method(self, _2, _1); \ - else \ - ret = NotImplemented; \ - } \ - if(is_not_implemented(ret)) { \ - PyVar self; \ - PyVar _2 = get_unbound_method(_1, rfunc, &self, false); \ - if(_2.type) \ - ret = call_method(self, _2, _0); \ - else \ - BinaryOptError(op, _0, _1); \ - if(is_not_implemented(ret)) BinaryOptError(op, _0, _1); \ - } +// #define BINARY_F_COMPARE(func, op, rfunc) \ +// PyVar ret; \ +// const PyTypeInfo* _ti = _tp_info(_0); \ +// if(_ti->m##func) { \ +// ret = _ti->m##func(this, _0, _1); \ +// } else { \ +// PyVar self; \ +// PyVar _2 = get_unbound_method(_0, func, &self, false); \ +// if(_2.type) \ +// ret = call_method(self, _2, _1); \ +// else \ +// ret = NotImplemented; \ +// } \ +// if(is_not_implemented(ret)) { \ +// PyVar self; \ +// PyVar _2 = get_unbound_method(_1, rfunc, &self, false); \ +// if(_2.type) \ +// ret = call_method(self, _2, _0); \ +// else \ +// BinaryOptError(op, _0, _1); \ +// if(is_not_implemented(ret)) BinaryOptError(op, _0, _1); \ +// } -void VM::__op_unpack_sequence(uint16_t arg) { - PyVar _0 = POPX(); - if(is_type(_0, VM::tp_tuple)) { - // fast path for tuple - Tuple& tuple = PK_OBJ_GET(Tuple, _0); - if(tuple.size() == arg) { - for(PyVar obj: tuple) - PUSH(obj); - } else { - ValueError(_S("expected ", (int)arg, " values to unpack, got ", (int)tuple.size())); - } - } else { - auto _lock = gc_scope_lock(); // lock the gc via RAII!! - _0 = py_iter(_0); - const PyTypeInfo* ti = _tp_info(_0); - for(int i = 0; i < arg; i++) { - PyVar _1 = _py_next(ti, _0); - if(_1 == StopIteration) ValueError("not enough values to unpack"); - PUSH(_1); - } - if(_py_next(ti, _0) != StopIteration) ValueError("too many values to unpack"); - } -} +// void VM::__op_unpack_sequence(uint16_t arg) { +// PyVar _0 = POPX(); +// if(is_type(_0, VM::tp_tuple)) { +// // fast path for tuple +// Tuple& tuple = PK_OBJ_GET(Tuple, _0); +// if(tuple.size() == arg) { +// for(PyVar obj: tuple) +// PUSH(obj); +// } else { +// ValueError(_S("expected ", (int)arg, " values to unpack, got ", (int)tuple.size())); +// } +// } else { +// auto _lock = gc_scope_lock(); // lock the gc via RAII!! +// _0 = py_iter(_0); +// const PyTypeInfo* ti = _tp_info(_0); +// for(int i = 0; i < arg; i++) { +// PyVar _1 = _py_next(ti, _0); +// if(_1 == StopIteration) ValueError("not enough values to unpack"); +// PUSH(_1); +// } +// if(_py_next(ti, _0) != StopIteration) ValueError("too many values to unpack"); +// } +// } -bool VM::py_lt(PyVar _0, PyVar _1) { - BINARY_F_COMPARE(__lt__, "<", __gt__); - assert(ret.type == tp_bool); - return ret.extra; -} +// bool VM::py_lt(PyVar _0, PyVar _1) { +// BINARY_F_COMPARE(__lt__, "<", __gt__); +// assert(ret.type == tp_bool); +// return ret.extra; +// } -bool VM::py_le(PyVar _0, PyVar _1) { - BINARY_F_COMPARE(__le__, "<=", __ge__); - assert(ret.type == tp_bool); - return ret.extra; -} +// bool VM::py_le(PyVar _0, PyVar _1) { +// BINARY_F_COMPARE(__le__, "<=", __ge__); +// assert(ret.type == tp_bool); +// return ret.extra; +// } -bool VM::py_gt(PyVar _0, PyVar _1) { - BINARY_F_COMPARE(__gt__, ">", __lt__); - assert(ret.type == tp_bool); - return ret.extra; -} +// bool VM::py_gt(PyVar _0, PyVar _1) { +// BINARY_F_COMPARE(__gt__, ">", __lt__); +// assert(ret.type == tp_bool); +// return ret.extra; +// } -bool VM::py_ge(PyVar _0, PyVar _1) { - BINARY_F_COMPARE(__ge__, ">=", __le__); - assert(ret.type == tp_bool); - return ret.extra; -} +// bool VM::py_ge(PyVar _0, PyVar _1) { +// BINARY_F_COMPARE(__ge__, ">=", __le__); +// assert(ret.type == tp_bool); +// return ret.extra; +// } -#undef BINARY_F_COMPARE +// #undef BINARY_F_COMPARE -#if PK_ENABLE_PROFILER -#define CEVAL_STEP_CALLBACK() \ - if(_ceval_on_step) _ceval_on_step(this, frame, byte); \ - if(_profiler) _profiler->_step(callstack.size(), frame); \ - if(!_next_breakpoint.empty()) { _next_breakpoint._step(this); } -#else -#define CEVAL_STEP_CALLBACK() \ - if(_ceval_on_step && _ceval_on_step) { \ - if(_ceval_on_step) \ - if(_ceval_on_step) _ceval_on_step(this, frame, byte); \ - } -#endif +// #if PK_ENABLE_PROFILER +// #define CEVAL_STEP_CALLBACK() \ +// if(_ceval_on_step) _ceval_on_step(this, frame, byte); \ +// if(_profiler) _profiler->_step(callstack.size(), frame); \ +// if(!_next_breakpoint.empty()) { _next_breakpoint._step(this); } +// #else +// #define CEVAL_STEP_CALLBACK() \ +// if(_ceval_on_step && _ceval_on_step) { \ +// if(_ceval_on_step) \ +// if(_ceval_on_step) _ceval_on_step(this, frame, byte); \ +// } +// #endif -#define DISPATCH() \ - { \ - frame->_ip++; \ - goto __NEXT_STEP; \ - } -#define DISPATCH_JUMP(__offset) \ - { \ - frame->_ip += __offset; \ - goto __NEXT_STEP; \ - } -#define DISPATCH_JUMP_ABSOLUTE(__target) \ - { \ - frame->_ip = c11__at(Bytecode, &frame->co->codes, __target); \ - goto __NEXT_STEP; \ - } +// #define DISPATCH() \ +// { \ +// frame->_ip++; \ +// goto __NEXT_STEP; \ +// } +// #define DISPATCH_JUMP(__offset) \ +// { \ +// frame->_ip += __offset; \ +// goto __NEXT_STEP; \ +// } +// #define DISPATCH_JUMP_ABSOLUTE(__target) \ +// { \ +// frame->_ip = c11__at(Bytecode, &frame->co->codes, __target); \ +// goto __NEXT_STEP; \ +// } -PyVar VM::__run_top_frame() { - Frame* frame = &callstack.top(); - const Frame* base_frame = frame; - InternalException __internal_exception; +// PyVar VM::__run_top_frame() { +// Frame* frame = &callstack.top(); +// const Frame* base_frame = frame; +// InternalException __internal_exception; - while(true) { - try { - /**********************************************************************/ - { - __NEXT_FRAME: - Bytecode byte; +// while(true) { +// try { +// /**********************************************************************/ +// { +// __NEXT_FRAME: +// Bytecode byte; - 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 - } +// 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 +// } - __NEXT_STEP: - byte = *frame->_ip; - CEVAL_STEP_CALLBACK() +// __NEXT_STEP: +// byte = *frame->_ip; +// CEVAL_STEP_CALLBACK() -#if PK_DEBUG_CEVAL_STEP - __log_s_data(); -#endif - switch((Opcode)byte.op) { - case OP_NO_OP: DISPATCH() - /*****************************************/ - case OP_POP_TOP: POP(); DISPATCH() - case OP_DUP_TOP: PUSH(TOP()); DISPATCH() - case OP_DUP_TOP_TWO: - // [a, b] - PUSH(SECOND()); // [a, b, a] - PUSH(SECOND()); // [a, b, a, b] - DISPATCH() - case OP_ROT_TWO: std::swap(TOP(), SECOND()); DISPATCH() - case OP_ROT_THREE: { - // [a, b, c] -> [c, a, b] - PyVar _0 = TOP(); - TOP() = SECOND(); - SECOND() = THIRD(); - THIRD() = _0; - } - DISPATCH() - case OP_PRINT_EXPR: - if(!is_none(TOP())) stdout_write(py_repr(TOP()) + "\n"); - POP(); - DISPATCH() - /*****************************************/ - case OP_LOAD_CONST: - PUSH(c11__getitem(PyVar, &frame->co->consts, byte.arg)); - DISPATCH() - case OP_LOAD_NONE: PUSH(None); DISPATCH() - case OP_LOAD_TRUE: PUSH(True); DISPATCH() - case OP_LOAD_FALSE: PUSH(False); DISPATCH() - /*****************************************/ - case OP_LOAD_SMALL_INT: s_data.emplace(tp_int, (i64)(int16_t)byte.arg); DISPATCH() - /*****************************************/ - case OP_LOAD_ELLIPSIS: PUSH(Ellipsis); DISPATCH() - case OP_LOAD_FUNCTION: { - FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg); - PyVar obj; - if(decl->nested) { - NameDict* captured = frame->_locals.to_namedict(); - obj = new_object(tp_function, decl, frame->_module, nullptr, captured); - uint16_t name = pk_StrName__map2(pkpy_Str__sv(&decl->code->name)); - captured->set(name, obj); - } else { - obj = new_object(tp_function, decl, frame->_module, nullptr, nullptr); - } - PUSH(obj); - } - DISPATCH() - case OP_LOAD_NULL: PUSH(PY_NULL); DISPATCH() - /*****************************************/ - case OP_LOAD_FAST: { - PyVar _0 = frame->_locals[byte.arg]; - if(_0 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); - PUSH(_0); - } - DISPATCH() - case OP_LOAD_NAME: { - StrName _name(byte.arg); - PyVar* slot = frame->_locals.try_get_name(_name); - if(slot != nullptr) { - if(*slot == PY_NULL) vm->UnboundLocalError(_name); - PUSH(*slot); - DISPATCH() - } - PyVar* _0 = frame->f_closure_try_get(_name); - if(_0 != nullptr) { - PUSH(*_0); - DISPATCH() - } - _0 = frame->f_globals().try_get_2_likely_found(_name); - if(_0 != nullptr) { - PUSH(*_0); - DISPATCH() - } - _0 = vm->builtins->attr().try_get_2_likely_found(_name); - if(_0 != nullptr) { - PUSH(*_0); - DISPATCH() - } - vm->NameError(_name); - } - DISPATCH() - case OP_LOAD_NONLOCAL: { - StrName _name(byte.arg); - PyVar* _0 = frame->f_closure_try_get(_name); - if(_0 != nullptr) { - PUSH(*_0); - DISPATCH() - } - _0 = frame->f_globals().try_get_2_likely_found(_name); - if(_0 != nullptr) { - PUSH(*_0); - DISPATCH() - } - _0 = vm->builtins->attr().try_get_2_likely_found(_name); - if(_0 != nullptr) { - PUSH(*_0); - DISPATCH() - } - vm->NameError(_name); - } - DISPATCH() - case OP_LOAD_GLOBAL: { - StrName _name(byte.arg); - PyVar _0 = frame->f_globals().try_get_likely_found(_name); - if(_0 != nullptr) { - PUSH(_0); - DISPATCH() - } - _0 = vm->builtins->attr().try_get_likely_found(_name); - if(_0 != nullptr) { - PUSH(_0); - DISPATCH() - } - vm->NameError(_name); - } - DISPATCH() - case OP_LOAD_ATTR: { - TOP() = getattr(TOP(), StrName(byte.arg)); - } - DISPATCH() - case OP_LOAD_CLASS_GLOBAL: { - assert(__curr_class != nullptr); - StrName _name(byte.arg); - PyVar _0 = getattr(__curr_class, _name, false); - if(_0 != nullptr) { - PUSH(_0); - DISPATCH() - } - // load global if attribute not found - _0 = frame->f_globals().try_get_likely_found(_name); - if(_0 != nullptr) { - PUSH(_0); - DISPATCH() - } - _0 = vm->builtins->attr().try_get_likely_found(_name); - if(_0 != nullptr) { - PUSH(_0); - DISPATCH() - } - vm->NameError(_name); - } - DISPATCH() - case OP_LOAD_METHOD: { - PyVar _0; - TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true); - PUSH(_0); - } - DISPATCH() - case OP_LOAD_SUBSCR: { - PyVar _1 = POPX(); // b - PyVar _0 = TOP(); // a - auto _ti = _tp_info(_0); - if(_ti->m__getitem__) { - TOP() = _ti->m__getitem__(this, _0, _1); - } else { - TOP() = call_method(_0, __getitem__, _1); - } - } - DISPATCH() - case OP_LOAD_SUBSCR_FAST: { - PyVar _1 = frame->_locals[byte.arg]; - if(_1 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); - PyVar _0 = TOP(); // a - auto _ti = _tp_info(_0); - if(_ti->m__getitem__) { - TOP() = _ti->m__getitem__(this, _0, _1); - } else { - TOP() = call_method(_0, __getitem__, _1); - } - } - DISPATCH() - case OP_LOAD_SUBSCR_SMALL_INT: { - PyVar _1 = VAR((int16_t)byte.arg); - PyVar _0 = TOP(); // a - auto _ti = _tp_info(_0); - if(_ti->m__getitem__) { - TOP() = _ti->m__getitem__(this, _0, _1); - } else { - TOP() = call_method(_0, __getitem__, _1); - } - } - DISPATCH() - case OP_STORE_FAST: frame->_locals[byte.arg] = POPX(); DISPATCH() - case OP_STORE_NAME: { - StrName _name(byte.arg); - PyVar _0 = POPX(); - if(frame->_callable != nullptr) { - PyVar* slot = frame->_locals.try_get_name(_name); - if(slot != nullptr) { - *slot = _0; // store in locals if possible - } else { - Function& func = frame->_callable->as(); - if(func.decl == __dynamic_func_decl) { - assert(func._closure != nullptr); - func._closure->set(_name, _0); - } else { - vm->NameError(_name); - } - } - } else { - frame->f_globals().set(_name, _0); - } - } - DISPATCH() - case OP_STORE_GLOBAL: frame->f_globals().set(StrName(byte.arg), POPX()); DISPATCH() - case OP_STORE_ATTR: { - PyVar _0 = TOP(); // a - PyVar _1 = SECOND(); // val - setattr(_0, StrName(byte.arg), _1); - STACK_SHRINK(2); - } - DISPATCH() - case OP_STORE_SUBSCR: { - PyVar _2 = POPX(); // b - PyVar _1 = POPX(); // a - PyVar _0 = POPX(); // val - auto _ti = _tp_info(_1); - if(_ti->m__setitem__) { - _ti->m__setitem__(this, _1, _2, _0); - } else { - call_method(_1, __setitem__, _2, _0); - } - } - DISPATCH() - case OP_STORE_SUBSCR_FAST: { - PyVar _2 = frame->_locals[byte.arg]; // b - if(_2 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); - PyVar _1 = POPX(); // a - PyVar _0 = POPX(); // val - auto _ti = _tp_info(_1); - if(_ti->m__setitem__) { - _ti->m__setitem__(this, _1, _2, _0); - } else { - call_method(_1, __setitem__, _2, _0); - } - } - DISPATCH() - case OP_DELETE_FAST: { - PyVar _0 = frame->_locals[byte.arg]; - if(_0 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); - frame->_locals[byte.arg].set_null(); - } - DISPATCH() - case OP_DELETE_NAME: { - StrName _name(byte.arg); - if(frame->_callable != nullptr) { - PyVar* slot = frame->_locals.try_get_name(_name); - if(slot != nullptr) { - slot->set_null(); - } else { - Function& func = frame->_callable->as(); - if(func.decl == __dynamic_func_decl) { - assert(func._closure != nullptr); - bool ok = func._closure->del(_name); - if(!ok) vm->NameError(_name); - } else { - vm->NameError(_name); - } - } - } else { - if(!frame->f_globals().del(_name)) vm->NameError(_name); - } - } - DISPATCH() - case OP_DELETE_GLOBAL: { - StrName _name(byte.arg); - if(!frame->f_globals().del(_name)) vm->NameError(_name); - } - DISPATCH() - case OP_DELETE_ATTR: { - PyVar _0 = POPX(); - delattr(_0, StrName(byte.arg)); - } - DISPATCH() - case OP_DELETE_SUBSCR: { - PyVar _1 = POPX(); - PyVar _0 = POPX(); - auto _ti = _tp_info(_0); - if(_ti->m__delitem__) { - _ti->m__delitem__(this, _0, _1); - } else { - call_method(_0, __delitem__, _1); - } - } - DISPATCH() - /*****************************************/ - case OP_BUILD_LONG: { - PyVar _0 = builtins->attr().try_get_likely_found(pk_id_long); - if(_0 == nullptr) AttributeError(builtins, pk_id_long); - TOP() = call(_0, TOP()); - } - DISPATCH() - case OP_BUILD_IMAG: { - PyVar _0 = builtins->attr().try_get_likely_found(pk_id_complex); - if(_0 == nullptr) AttributeError(builtins, pk_id_long); - TOP() = call(_0, VAR(0), TOP()); - } - DISPATCH() - case OP_BUILD_BYTES: { - const Str& s = CAST(Str&, TOP()); - unsigned char* p = (unsigned char*)std::malloc(s.size); - std::memcpy(p, s.c_str(), s.size); - TOP() = VAR(Bytes(p, s.size)); - } - DISPATCH() - case OP_BUILD_TUPLE: { - PyVar _0 = VAR(STACK_VIEW(byte.arg).to_tuple()); - STACK_SHRINK(byte.arg); - PUSH(_0); - } - DISPATCH() - case OP_BUILD_LIST: { - PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); - STACK_SHRINK(byte.arg); - PUSH(_0); - } - DISPATCH() - case OP_BUILD_DICT: { - if(byte.arg == 0) { - PUSH(VAR(Dict())); - DISPATCH() - } - PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); - _0 = call(_t(tp_dict), _0); - STACK_SHRINK(byte.arg); - PUSH(_0); - } - DISPATCH() - case OP_BUILD_SET: { - PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); - _0 = call(builtins->attr()[pk_id_set], _0); - STACK_SHRINK(byte.arg); - PUSH(_0); - } - DISPATCH() - case OP_BUILD_SLICE: { - PyVar _2 = POPX(); // step - PyVar _1 = POPX(); // stop - PyVar _0 = POPX(); // start - PUSH(VAR(Slice(_0, _1, _2))); - } - DISPATCH() - case OP_BUILD_STRING: { - SStream ss; - ArgsView view = STACK_VIEW(byte.arg); - for(PyVar obj: view) - ss << py_str(obj); - STACK_SHRINK(byte.arg); - PUSH(VAR(ss.str())); - } - DISPATCH() - /*****************************************/ - case OP_BUILD_TUPLE_UNPACK: { - List list; - __unpack_as_list(STACK_VIEW(byte.arg), list); - STACK_SHRINK(byte.arg); - PyVar _0 = VAR(list.to_tuple()); - PUSH(_0); - } - DISPATCH() - case OP_BUILD_LIST_UNPACK: { - List list; - __unpack_as_list(STACK_VIEW(byte.arg), list); - STACK_SHRINK(byte.arg); - PyVar _0 = VAR(std::move(list)); - PUSH(_0); - } - DISPATCH() - case OP_BUILD_DICT_UNPACK: { - Dict dict; - __unpack_as_dict(STACK_VIEW(byte.arg), dict); - STACK_SHRINK(byte.arg); - PyVar _0 = VAR(std::move(dict)); - PUSH(_0); - } - DISPATCH() - case OP_BUILD_SET_UNPACK: { - List list; - __unpack_as_list(STACK_VIEW(byte.arg), list); - STACK_SHRINK(byte.arg); - PyVar _0 = VAR(std::move(list)); - _0 = call(builtins->attr()[pk_id_set], _0); - PUSH(_0); - } - DISPATCH() - /*****************************************/ -#define BINARY_OP_SPECIAL(func) \ - _ti = _tp_info(_0); \ - if(_ti->m##func) { \ - TOP() = _ti->m##func(this, _0, _1); \ - } else { \ - PyVar self; \ - PyVar _2 = get_unbound_method(_0, func, &self, false); \ - if(_2 != nullptr) \ - TOP() = call_method(self, _2, _1); \ - else \ - TOP() = NotImplemented; \ - } +// #if PK_DEBUG_CEVAL_STEP +// __log_s_data(); +// #endif +// switch((Opcode)byte.op) { +// case OP_NO_OP: DISPATCH() +// /*****************************************/ +// case OP_POP_TOP: POP(); DISPATCH() +// case OP_DUP_TOP: PUSH(TOP()); DISPATCH() +// case OP_DUP_TOP_TWO: +// // [a, b] +// PUSH(SECOND()); // [a, b, a] +// PUSH(SECOND()); // [a, b, a, b] +// DISPATCH() +// case OP_ROT_TWO: std::swap(TOP(), SECOND()); DISPATCH() +// case OP_ROT_THREE: { +// // [a, b, c] -> [c, a, b] +// PyVar _0 = TOP(); +// TOP() = SECOND(); +// SECOND() = THIRD(); +// THIRD() = _0; +// } +// DISPATCH() +// case OP_PRINT_EXPR: +// if(!is_none(TOP())) stdout_write(py_repr(TOP()) + "\n"); +// POP(); +// DISPATCH() +// /*****************************************/ +// case OP_LOAD_CONST: +// PUSH(c11__getitem(PyVar, &frame->co->consts, byte.arg)); +// DISPATCH() +// case OP_LOAD_NONE: PUSH(None); DISPATCH() +// case OP_LOAD_TRUE: PUSH(True); DISPATCH() +// case OP_LOAD_FALSE: PUSH(False); DISPATCH() +// /*****************************************/ +// case OP_LOAD_SMALL_INT: s_data.emplace(tp_int, (i64)(int16_t)byte.arg); DISPATCH() +// /*****************************************/ +// case OP_LOAD_ELLIPSIS: PUSH(Ellipsis); DISPATCH() +// case OP_LOAD_FUNCTION: { +// FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg); +// PyVar obj; +// if(decl->nested) { +// NameDict* captured = frame->_locals.to_namedict(); +// obj = new_object(tp_function, decl, frame->_module, nullptr, captured); +// uint16_t name = pk_StrName__map2(pkpy_Str__sv(&decl->code->name)); +// captured->set(name, obj); +// } else { +// obj = new_object(tp_function, decl, frame->_module, nullptr, nullptr); +// } +// PUSH(obj); +// } +// DISPATCH() +// case OP_LOAD_NULL: PUSH(PY_NULL); DISPATCH() +// /*****************************************/ +// case OP_LOAD_FAST: { +// PyVar _0 = frame->_locals[byte.arg]; +// if(_0 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); +// PUSH(_0); +// } +// DISPATCH() +// case OP_LOAD_NAME: { +// StrName _name(byte.arg); +// PyVar* slot = frame->_locals.try_get_name(_name); +// if(slot != nullptr) { +// if(*slot == PY_NULL) vm->UnboundLocalError(_name); +// PUSH(*slot); +// DISPATCH() +// } +// PyVar* _0 = frame->f_closure_try_get(_name); +// if(_0 != nullptr) { +// PUSH(*_0); +// DISPATCH() +// } +// _0 = frame->f_globals().try_get_2_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(*_0); +// DISPATCH() +// } +// _0 = vm->builtins->attr().try_get_2_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(*_0); +// DISPATCH() +// } +// vm->NameError(_name); +// } +// DISPATCH() +// case OP_LOAD_NONLOCAL: { +// StrName _name(byte.arg); +// PyVar* _0 = frame->f_closure_try_get(_name); +// if(_0 != nullptr) { +// PUSH(*_0); +// DISPATCH() +// } +// _0 = frame->f_globals().try_get_2_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(*_0); +// DISPATCH() +// } +// _0 = vm->builtins->attr().try_get_2_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(*_0); +// DISPATCH() +// } +// vm->NameError(_name); +// } +// DISPATCH() +// case OP_LOAD_GLOBAL: { +// StrName _name(byte.arg); +// PyVar _0 = frame->f_globals().try_get_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(_0); +// DISPATCH() +// } +// _0 = vm->builtins->attr().try_get_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(_0); +// DISPATCH() +// } +// vm->NameError(_name); +// } +// DISPATCH() +// case OP_LOAD_ATTR: { +// TOP() = getattr(TOP(), StrName(byte.arg)); +// } +// DISPATCH() +// case OP_LOAD_CLASS_GLOBAL: { +// assert(__curr_class != nullptr); +// StrName _name(byte.arg); +// PyVar _0 = getattr(__curr_class, _name, false); +// if(_0 != nullptr) { +// PUSH(_0); +// DISPATCH() +// } +// // load global if attribute not found +// _0 = frame->f_globals().try_get_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(_0); +// DISPATCH() +// } +// _0 = vm->builtins->attr().try_get_likely_found(_name); +// if(_0 != nullptr) { +// PUSH(_0); +// DISPATCH() +// } +// vm->NameError(_name); +// } +// DISPATCH() +// case OP_LOAD_METHOD: { +// PyVar _0; +// TOP() = get_unbound_method(TOP(), StrName(byte.arg), &_0, true, true); +// PUSH(_0); +// } +// DISPATCH() +// case OP_LOAD_SUBSCR: { +// PyVar _1 = POPX(); // b +// PyVar _0 = TOP(); // a +// auto _ti = _tp_info(_0); +// if(_ti->m__getitem__) { +// TOP() = _ti->m__getitem__(this, _0, _1); +// } else { +// TOP() = call_method(_0, __getitem__, _1); +// } +// } +// DISPATCH() +// case OP_LOAD_SUBSCR_FAST: { +// PyVar _1 = frame->_locals[byte.arg]; +// if(_1 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); +// PyVar _0 = TOP(); // a +// auto _ti = _tp_info(_0); +// if(_ti->m__getitem__) { +// TOP() = _ti->m__getitem__(this, _0, _1); +// } else { +// TOP() = call_method(_0, __getitem__, _1); +// } +// } +// DISPATCH() +// case OP_LOAD_SUBSCR_SMALL_INT: { +// PyVar _1 = VAR((int16_t)byte.arg); +// PyVar _0 = TOP(); // a +// auto _ti = _tp_info(_0); +// if(_ti->m__getitem__) { +// TOP() = _ti->m__getitem__(this, _0, _1); +// } else { +// TOP() = call_method(_0, __getitem__, _1); +// } +// } +// DISPATCH() +// case OP_STORE_FAST: frame->_locals[byte.arg] = POPX(); DISPATCH() +// case OP_STORE_NAME: { +// StrName _name(byte.arg); +// PyVar _0 = POPX(); +// if(frame->_callable != nullptr) { +// PyVar* slot = frame->_locals.try_get_name(_name); +// if(slot != nullptr) { +// *slot = _0; // store in locals if possible +// } else { +// Function& func = frame->_callable->as(); +// if(func.decl == __dynamic_func_decl) { +// assert(func._closure != nullptr); +// func._closure->set(_name, _0); +// } else { +// vm->NameError(_name); +// } +// } +// } else { +// frame->f_globals().set(_name, _0); +// } +// } +// DISPATCH() +// case OP_STORE_GLOBAL: frame->f_globals().set(StrName(byte.arg), POPX()); DISPATCH() +// case OP_STORE_ATTR: { +// PyVar _0 = TOP(); // a +// PyVar _1 = SECOND(); // val +// setattr(_0, StrName(byte.arg), _1); +// STACK_SHRINK(2); +// } +// DISPATCH() +// case OP_STORE_SUBSCR: { +// PyVar _2 = POPX(); // b +// PyVar _1 = POPX(); // a +// PyVar _0 = POPX(); // val +// auto _ti = _tp_info(_1); +// if(_ti->m__setitem__) { +// _ti->m__setitem__(this, _1, _2, _0); +// } else { +// call_method(_1, __setitem__, _2, _0); +// } +// } +// DISPATCH() +// case OP_STORE_SUBSCR_FAST: { +// PyVar _2 = frame->_locals[byte.arg]; // b +// if(_2 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); +// PyVar _1 = POPX(); // a +// PyVar _0 = POPX(); // val +// auto _ti = _tp_info(_1); +// if(_ti->m__setitem__) { +// _ti->m__setitem__(this, _1, _2, _0); +// } else { +// call_method(_1, __setitem__, _2, _0); +// } +// } +// DISPATCH() +// case OP_DELETE_FAST: { +// PyVar _0 = frame->_locals[byte.arg]; +// if(_0 == PY_NULL) vm->UnboundLocalError(c11__getitem(uint16_t, &frame->co->varnames, byte.arg)); +// frame->_locals[byte.arg].set_null(); +// } +// DISPATCH() +// case OP_DELETE_NAME: { +// StrName _name(byte.arg); +// if(frame->_callable != nullptr) { +// PyVar* slot = frame->_locals.try_get_name(_name); +// if(slot != nullptr) { +// slot->set_null(); +// } else { +// Function& func = frame->_callable->as(); +// if(func.decl == __dynamic_func_decl) { +// assert(func._closure != nullptr); +// bool ok = func._closure->del(_name); +// if(!ok) vm->NameError(_name); +// } else { +// vm->NameError(_name); +// } +// } +// } else { +// if(!frame->f_globals().del(_name)) vm->NameError(_name); +// } +// } +// DISPATCH() +// case OP_DELETE_GLOBAL: { +// StrName _name(byte.arg); +// if(!frame->f_globals().del(_name)) vm->NameError(_name); +// } +// DISPATCH() +// case OP_DELETE_ATTR: { +// PyVar _0 = POPX(); +// delattr(_0, StrName(byte.arg)); +// } +// DISPATCH() +// case OP_DELETE_SUBSCR: { +// PyVar _1 = POPX(); +// PyVar _0 = POPX(); +// auto _ti = _tp_info(_0); +// if(_ti->m__delitem__) { +// _ti->m__delitem__(this, _0, _1); +// } else { +// call_method(_0, __delitem__, _1); +// } +// } +// DISPATCH() +// /*****************************************/ +// case OP_BUILD_LONG: { +// PyVar _0 = builtins->attr().try_get_likely_found(pk_id_long); +// if(_0 == nullptr) AttributeError(builtins, pk_id_long); +// TOP() = call(_0, TOP()); +// } +// DISPATCH() +// case OP_BUILD_IMAG: { +// PyVar _0 = builtins->attr().try_get_likely_found(pk_id_complex); +// if(_0 == nullptr) AttributeError(builtins, pk_id_long); +// TOP() = call(_0, VAR(0), TOP()); +// } +// DISPATCH() +// case OP_BUILD_BYTES: { +// const Str& s = CAST(Str&, TOP()); +// unsigned char* p = (unsigned char*)std::malloc(s.size); +// std::memcpy(p, s.c_str(), s.size); +// TOP() = VAR(Bytes(p, s.size)); +// } +// DISPATCH() +// case OP_BUILD_TUPLE: { +// PyVar _0 = VAR(STACK_VIEW(byte.arg).to_tuple()); +// STACK_SHRINK(byte.arg); +// PUSH(_0); +// } +// DISPATCH() +// case OP_BUILD_LIST: { +// PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); +// STACK_SHRINK(byte.arg); +// PUSH(_0); +// } +// DISPATCH() +// case OP_BUILD_DICT: { +// if(byte.arg == 0) { +// PUSH(VAR(Dict())); +// DISPATCH() +// } +// PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); +// _0 = call(_t(tp_dict), _0); +// STACK_SHRINK(byte.arg); +// PUSH(_0); +// } +// DISPATCH() +// case OP_BUILD_SET: { +// PyVar _0 = VAR(STACK_VIEW(byte.arg).to_list()); +// _0 = call(builtins->attr()[pk_id_set], _0); +// STACK_SHRINK(byte.arg); +// PUSH(_0); +// } +// DISPATCH() +// case OP_BUILD_SLICE: { +// PyVar _2 = POPX(); // step +// PyVar _1 = POPX(); // stop +// PyVar _0 = POPX(); // start +// PUSH(VAR(Slice(_0, _1, _2))); +// } +// DISPATCH() +// case OP_BUILD_STRING: { +// SStream ss; +// ArgsView view = STACK_VIEW(byte.arg); +// for(PyVar obj: view) +// ss << py_str(obj); +// STACK_SHRINK(byte.arg); +// PUSH(VAR(ss.str())); +// } +// DISPATCH() +// /*****************************************/ +// case OP_BUILD_TUPLE_UNPACK: { +// List list; +// __unpack_as_list(STACK_VIEW(byte.arg), list); +// STACK_SHRINK(byte.arg); +// PyVar _0 = VAR(list.to_tuple()); +// PUSH(_0); +// } +// DISPATCH() +// case OP_BUILD_LIST_UNPACK: { +// List list; +// __unpack_as_list(STACK_VIEW(byte.arg), list); +// STACK_SHRINK(byte.arg); +// PyVar _0 = VAR(std::move(list)); +// PUSH(_0); +// } +// DISPATCH() +// case OP_BUILD_DICT_UNPACK: { +// Dict dict; +// __unpack_as_dict(STACK_VIEW(byte.arg), dict); +// STACK_SHRINK(byte.arg); +// PyVar _0 = VAR(std::move(dict)); +// PUSH(_0); +// } +// DISPATCH() +// case OP_BUILD_SET_UNPACK: { +// List list; +// __unpack_as_list(STACK_VIEW(byte.arg), list); +// STACK_SHRINK(byte.arg); +// PyVar _0 = VAR(std::move(list)); +// _0 = call(builtins->attr()[pk_id_set], _0); +// PUSH(_0); +// } +// DISPATCH() +// /*****************************************/ +// #define BINARY_OP_SPECIAL(func) \ +// _ti = _tp_info(_0); \ +// if(_ti->m##func) { \ +// TOP() = _ti->m##func(this, _0, _1); \ +// } else { \ +// PyVar self; \ +// PyVar _2 = get_unbound_method(_0, func, &self, false); \ +// if(_2 != nullptr) \ +// TOP() = call_method(self, _2, _1); \ +// else \ +// TOP() = NotImplemented; \ +// } -#define BINARY_OP_RSPECIAL(op, func) \ - if(is_not_implemented(TOP())) { \ - PyVar self; \ - PyVar _2 = get_unbound_method(_1, func, &self, false); \ - if(_2 != nullptr) \ - TOP() = call_method(self, _2, _0); \ - else \ - BinaryOptError(op, _0, _1); \ - if(is_not_implemented(TOP())) BinaryOptError(op, _0, _1); \ - } +// #define BINARY_OP_RSPECIAL(op, func) \ +// if(is_not_implemented(TOP())) { \ +// PyVar self; \ +// PyVar _2 = get_unbound_method(_1, func, &self, false); \ +// if(_2 != nullptr) \ +// TOP() = call_method(self, _2, _0); \ +// else \ +// BinaryOptError(op, _0, _1); \ +// if(is_not_implemented(TOP())) BinaryOptError(op, _0, _1); \ +// } - case OP_BINARY_TRUEDIV: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__truediv__); - if(is_not_implemented(TOP())) BinaryOptError("/", _0, _1); - } - DISPATCH() - case OP_BINARY_POW: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__pow__); - if(is_not_implemented(TOP())) BinaryOptError("**", _0, _1); - } - DISPATCH() - case OP_BINARY_ADD: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(+) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__add__); - BINARY_OP_RSPECIAL("+", __radd__); - } - DISPATCH() - case OP_BINARY_SUB: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(-) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__sub__); - BINARY_OP_RSPECIAL("-", __rsub__); - } - DISPATCH() - case OP_BINARY_MUL: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(*) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__mul__); - BINARY_OP_RSPECIAL("*", __rmul__); - } - DISPATCH() - case OP_BINARY_FLOORDIV: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_DIV_OP(/) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__floordiv__); - if(is_not_implemented(TOP())) BinaryOptError("//", _0, _1); - } - DISPATCH() - case OP_BINARY_MOD: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_DIV_OP(%) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__mod__); - if(is_not_implemented(TOP())) BinaryOptError("%", _0, _1); - } - DISPATCH() - case OP_COMPARE_LT: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(<) - TOP() = VAR(py_lt(_0, _1)); - } - DISPATCH() - case OP_COMPARE_LE: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(<=) - TOP() = VAR(py_le(_0, _1)); - } - DISPATCH() - case OP_COMPARE_EQ: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - TOP() = VAR(py_eq(_0, _1)); - } - DISPATCH() - case OP_COMPARE_NE: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - TOP() = VAR(py_ne(_0, _1)); - } - DISPATCH() - case OP_COMPARE_GT: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(>) - TOP() = VAR(py_gt(_0, _1)); - } - DISPATCH() - case OP_COMPARE_GE: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(>=) - TOP() = VAR(py_ge(_0, _1)); - } - DISPATCH() - case OP_BITWISE_LSHIFT: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(<<) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__lshift__); - if(is_not_implemented(TOP())) BinaryOptError("<<", _0, _1); - } - DISPATCH() - case OP_BITWISE_RSHIFT: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(>>) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__rshift__); - if(is_not_implemented(TOP())) BinaryOptError(">>", _0, _1); - } - DISPATCH() - case OP_BITWISE_AND: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(&) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__and__); - if(is_not_implemented(TOP())) BinaryOptError("&", _0, _1); - } - DISPATCH() - case OP_BITWISE_OR: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(|) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__or__); - if(is_not_implemented(TOP())) BinaryOptError("|", _0, _1); - } - DISPATCH() - case OP_BITWISE_XOR: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - PREDICT_INT_OP(^) - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__xor__); - if(is_not_implemented(TOP())) BinaryOptError("^", _0, _1); - } - DISPATCH() - case OP_BINARY_MATMUL: { - PyVar _1 = POPX(); - PyVar _0 = TOP(); - const PyTypeInfo* _ti; - BINARY_OP_SPECIAL(__matmul__); - if(is_not_implemented(TOP())) BinaryOptError("@", _0, _1); - } - DISPATCH() +// case OP_BINARY_TRUEDIV: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__truediv__); +// if(is_not_implemented(TOP())) BinaryOptError("/", _0, _1); +// } +// DISPATCH() +// case OP_BINARY_POW: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__pow__); +// if(is_not_implemented(TOP())) BinaryOptError("**", _0, _1); +// } +// DISPATCH() +// case OP_BINARY_ADD: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(+) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__add__); +// BINARY_OP_RSPECIAL("+", __radd__); +// } +// DISPATCH() +// case OP_BINARY_SUB: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(-) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__sub__); +// BINARY_OP_RSPECIAL("-", __rsub__); +// } +// DISPATCH() +// case OP_BINARY_MUL: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(*) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__mul__); +// BINARY_OP_RSPECIAL("*", __rmul__); +// } +// DISPATCH() +// case OP_BINARY_FLOORDIV: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_DIV_OP(/) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__floordiv__); +// if(is_not_implemented(TOP())) BinaryOptError("//", _0, _1); +// } +// DISPATCH() +// case OP_BINARY_MOD: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_DIV_OP(%) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__mod__); +// if(is_not_implemented(TOP())) BinaryOptError("%", _0, _1); +// } +// DISPATCH() +// case OP_COMPARE_LT: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(<) +// TOP() = VAR(py_lt(_0, _1)); +// } +// DISPATCH() +// case OP_COMPARE_LE: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(<=) +// TOP() = VAR(py_le(_0, _1)); +// } +// DISPATCH() +// case OP_COMPARE_EQ: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// TOP() = VAR(py_eq(_0, _1)); +// } +// DISPATCH() +// case OP_COMPARE_NE: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// TOP() = VAR(py_ne(_0, _1)); +// } +// DISPATCH() +// case OP_COMPARE_GT: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(>) +// TOP() = VAR(py_gt(_0, _1)); +// } +// DISPATCH() +// case OP_COMPARE_GE: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(>=) +// TOP() = VAR(py_ge(_0, _1)); +// } +// DISPATCH() +// case OP_BITWISE_LSHIFT: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(<<) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__lshift__); +// if(is_not_implemented(TOP())) BinaryOptError("<<", _0, _1); +// } +// DISPATCH() +// case OP_BITWISE_RSHIFT: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(>>) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__rshift__); +// if(is_not_implemented(TOP())) BinaryOptError(">>", _0, _1); +// } +// DISPATCH() +// case OP_BITWISE_AND: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(&) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__and__); +// if(is_not_implemented(TOP())) BinaryOptError("&", _0, _1); +// } +// DISPATCH() +// case OP_BITWISE_OR: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(|) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__or__); +// if(is_not_implemented(TOP())) BinaryOptError("|", _0, _1); +// } +// DISPATCH() +// case OP_BITWISE_XOR: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// PREDICT_INT_OP(^) +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__xor__); +// if(is_not_implemented(TOP())) BinaryOptError("^", _0, _1); +// } +// DISPATCH() +// case OP_BINARY_MATMUL: { +// PyVar _1 = POPX(); +// PyVar _0 = TOP(); +// const PyTypeInfo* _ti; +// BINARY_OP_SPECIAL(__matmul__); +// if(is_not_implemented(TOP())) BinaryOptError("@", _0, _1); +// } +// DISPATCH() -#undef BINARY_OP_SPECIAL -#undef BINARY_OP_RSPECIAL -#undef PREDICT_INT_OP +// #undef BINARY_OP_SPECIAL +// #undef BINARY_OP_RSPECIAL +// #undef PREDICT_INT_OP - case OP_IS_OP: { - PyVar _1 = POPX(); // rhs - PyVar _0 = TOP(); // lhs - TOP() = PyVar__IS_OP(&_0, &_1) ? True : False; - } - DISPATCH() - case OP_IS_NOT_OP: { - PyVar _1 = POPX(); // rhs - PyVar _0 = TOP(); // lhs - TOP() = PyVar__IS_OP(&_0, &_1) ? False : True; - } - DISPATCH() - case OP_CONTAINS_OP: { - // a in b -> b __contains__ a - auto _ti = _tp_info(TOP()); - PyVar _0; - if(_ti->m__contains__) { - _0 = _ti->m__contains__(this, TOP(), SECOND()); - } else { - _0 = call_method(TOP(), __contains__, SECOND()); - } - POP(); - TOP() = VAR(static_cast((int)CAST(bool, _0) ^ byte.arg)); - } - DISPATCH() - /*****************************************/ - case OP_JUMP_FORWARD: DISPATCH_JUMP((int16_t)byte.arg) - case OP_POP_JUMP_IF_FALSE: - if(!py_bool(POPX())) DISPATCH_JUMP((int16_t)byte.arg) - DISPATCH() - case OP_POP_JUMP_IF_TRUE: - if(py_bool(POPX())) DISPATCH_JUMP((int16_t)byte.arg) - DISPATCH() - case OP_JUMP_IF_TRUE_OR_POP: - if(py_bool(TOP())) { - DISPATCH_JUMP((int16_t)byte.arg) - } else { - POP(); - DISPATCH() - } - case OP_JUMP_IF_FALSE_OR_POP: - if(!py_bool(TOP())) { - DISPATCH_JUMP((int16_t)byte.arg) - } else { - POP(); - DISPATCH() - } - case OP_SHORTCUT_IF_FALSE_OR_POP: - if(!py_bool(TOP())) { // [b, False] - STACK_SHRINK(2); // [] - PUSH(vm->False); // [False] - DISPATCH_JUMP((int16_t)byte.arg) - } else { - POP(); // [b] - DISPATCH() - } - case OP_LOOP_CONTINUE: - // just an alias of OP_JUMP_FORWARD - DISPATCH_JUMP((int16_t)byte.arg) - case OP_LOOP_BREAK: { - frame->prepare_jump_break(&s_data, frame->ip() + byte.arg); - DISPATCH_JUMP((int16_t)byte.arg) - } - case OP_JUMP_ABSOLUTE_TOP: DISPATCH_JUMP_ABSOLUTE(_CAST(int, POPX())) - case OP_GOTO: { - StrName _name(byte.arg); - int target = c11_smallmap_n2i__get(&frame->co->labels, byte.arg, -1); - if(target < 0) RuntimeError(_S("label ", _name.escape(), " not found")); - frame->prepare_jump_break(&s_data, target); - DISPATCH_JUMP_ABSOLUTE(target) - } - /*****************************************/ - case OP_FSTRING_EVAL: { - PyVar _0 = c11__getitem(PyVar, &frame->co->consts, byte.arg); - std::string_view string = CAST(Str&, _0).sv(); - // TODO: optimize this - CodeObject* code = vm->compile(string, "", EVAL_MODE, true); - _0 = vm->_exec(code, frame->_module, frame->_callable, frame->_locals); - CodeObject__delete(code); - PUSH(_0); - } - DISPATCH() - case OP_REPR: TOP() = VAR(py_repr(TOP())); DISPATCH() - case OP_CALL: { - pk_ManagedHeap__collect_if_needed(&heap); - PyVar _0 = vectorcall(byte.arg & 0xFF, // ARGC - (byte.arg >> 8) & 0xFF, // KWARGC - true); - if(_0.type == tp_op_call) { - frame = &callstack.top(); - goto __NEXT_FRAME; - } - PUSH(_0); - } - DISPATCH() - case OP_CALL_TP: { - pk_ManagedHeap__collect_if_needed(&heap); - PyVar _0; - PyVar _1; - PyVar _2; - // [callable, , args: tuple, kwargs: dict | NULL] - if(byte.arg) { - _2 = POPX(); - _1 = POPX(); - for(PyVar obj: _CAST(Tuple&, _1)) - PUSH(obj); - _CAST(Dict&, _2).apply([this](PyVar k, PyVar v) { - PUSH(VAR(StrName(CAST(Str&, k)).index)); - PUSH(v); - }); - _0 = vectorcall(_CAST(Tuple&, _1).size(), // ARGC - _CAST(Dict&, _2).size(), // KWARGC - true); - } else { - // no **kwargs - _1 = POPX(); - for(PyVar obj: _CAST(Tuple&, _1)) - PUSH(obj); - _0 = vectorcall(_CAST(Tuple&, _1).size(), // ARGC - 0, // KWARGC - true); - } - if(_0.type == tp_op_call) { - frame = &callstack.top(); - goto __NEXT_FRAME; - } - PUSH(_0); - } - DISPATCH() - case OP_RETURN_VALUE: { - PyVar _0 = byte.arg == BC_NOARG ? POPX() : None; - __pop_frame(); - if(frame == base_frame) { // [ frameBase<- ] - return _0; - } else { - frame = &callstack.top(); - PUSH(_0); - goto __NEXT_FRAME; - } - } - DISPATCH() - case OP_YIELD_VALUE: return PY_OP_YIELD; - /*****************************************/ - case OP_LIST_APPEND: { - PyVar _0 = POPX(); - PK_OBJ_GET(List, SECOND()).push_back(_0); - } - DISPATCH() - case OP_DICT_ADD: { - PyVar _0 = POPX(); - const Tuple& t = PK_OBJ_GET(Tuple, _0); - PK_OBJ_GET(Dict, SECOND()).set(this, t[0], t[1]); - } - DISPATCH() - case OP_SET_ADD: { - PyVar _0 = POPX(); - call_method(SECOND(), pk_id_add, _0); - } - DISPATCH() - /*****************************************/ - case OP_UNARY_NEGATIVE: TOP() = py_negate(TOP()); DISPATCH() - case OP_UNARY_NOT: TOP() = VAR(!py_bool(TOP())); DISPATCH() - case OP_UNARY_STAR: TOP() = VAR(StarWrapper(byte.arg, TOP())); DISPATCH() - case OP_UNARY_INVERT: { - PyVar _0; - auto _ti = _tp_info(TOP()); - if(_ti->m__invert__) - _0 = _ti->m__invert__(this, TOP()); - else - _0 = call_method(TOP(), __invert__); - TOP() = _0; - } - DISPATCH() - /*****************************************/ - case OP_GET_ITER: TOP() = py_iter(TOP()); DISPATCH() - case OP_GET_ITER_NEW: TOP() = py_iter(TOP()); DISPATCH() - case OP_FOR_ITER: { - PyVar _0 = py_next(TOP()); - if(_0 == StopIteration) { - int target = frame->prepare_loop_break(&s_data); - DISPATCH_JUMP_ABSOLUTE(target) - } else { - PUSH(_0); - DISPATCH() - } - } - case OP_FOR_ITER_STORE_FAST: { - PyVar _0 = py_next(TOP()); - if(_0 == StopIteration) { - int target = frame->prepare_loop_break(&s_data); - DISPATCH_JUMP_ABSOLUTE(target) - } else { - frame->_locals[byte.arg] = _0; - DISPATCH() - } - } - case OP_FOR_ITER_STORE_GLOBAL: { - PyVar _0 = py_next(TOP()); - if(_0 == StopIteration) { - int target = frame->prepare_loop_break(&s_data); - DISPATCH_JUMP_ABSOLUTE(target) - } else { - frame->f_globals().set(StrName(byte.arg), _0); - DISPATCH() - } - } - case OP_FOR_ITER_YIELD_VALUE: { - PyVar _0 = py_next(TOP()); - if(_0 == StopIteration) { - int target = frame->prepare_loop_break(&s_data); - DISPATCH_JUMP_ABSOLUTE(target) - } else { - PUSH(_0); - return PY_OP_YIELD; - } - } - case OP_FOR_ITER_UNPACK: { - PyVar _0 = TOP(); - const PyTypeInfo* _ti = _tp_info(_0); - if(_ti->op__next__) { - unsigned n = _ti->op__next__(this, _0); - if(n == 0) { - // StopIteration - int target = frame->prepare_loop_break(&s_data); - DISPATCH_JUMP_ABSOLUTE(target) - } else if(n == 1) { - // UNPACK_SEQUENCE - __op_unpack_sequence(byte.arg); - } else { - if(n != byte.arg) { - ValueError(_S("expected ", (int)byte.arg, " values to unpack, got ", (int)n)); - } - } - } else { - // FOR_ITER - _0 = call_method(_0, __next__); - if(_0 != StopIteration) { - PUSH(_0); - // UNPACK_SEQUENCE - __op_unpack_sequence(byte.arg); - } else { - int target = frame->prepare_loop_break(&s_data); - DISPATCH_JUMP_ABSOLUTE(target) - } - } - } - DISPATCH() - /*****************************************/ - case OP_IMPORT_PATH: { - PyVar _0 = c11__getitem(PyVar, &frame->co->consts, byte.arg); - PUSH(py_import(CAST(Str&, _0))); - } - DISPATCH() - case OP_POP_IMPORT_STAR: { - PyVar _0 = POPX(); // pop the module - PyVar _1 = _0->attr().try_get(__all__); - StrName _name; - if(_1 != nullptr) { - for(PyVar key: CAST(List&, _1)) { - _name = StrName::get(CAST(Str&, key).sv()); - PyVar value = _0->attr().try_get_likely_found(_name); - if(value == nullptr) { - ImportError(_S("cannot import name ", _name.escape())); - } else { - frame->f_globals().set(_name, value); - } - } - } else { - for(auto& [name, value]: _0->attr().items()) { - std::string_view s = name.sv(); - if(s.empty() || s[0] == '_') continue; - frame->f_globals().set(name, value); - } - } - } - DISPATCH() - /*****************************************/ - case OP_UNPACK_SEQUENCE: { - __op_unpack_sequence(byte.arg); - } - DISPATCH() - case OP_UNPACK_EX: { - auto _lock = gc_scope_lock(); // lock the gc via RAII!! - PyVar _0 = py_iter(POPX()); - const PyTypeInfo* _ti = _tp_info(_0); - PyVar _1; - for(int i = 0; i < byte.arg; i++) { - _1 = _py_next(_ti, _0); - if(_1 == StopIteration) ValueError("not enough values to unpack"); - PUSH(_1); - } - List extras; - while(true) { - _1 = _py_next(_ti, _0); - if(_1 == StopIteration) break; - extras.push_back(_1); - } - PUSH(VAR(std::move(extras))); - } - DISPATCH() - /*****************************************/ - case OP_BEGIN_CLASS: { - StrName _name(byte.arg); - PyVar _0 = POPX(); // super - if(is_none(_0)) _0 = _t(tp_object); - check_type(_0, tp_type); - __curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0), true); - } - DISPATCH() - case OP_END_CLASS: { - assert(__curr_class != nullptr); - StrName _name(byte.arg); - frame->_module->attr().set(_name, __curr_class); - // call on_end_subclass - PyTypeInfo* ti = &_all_types[__curr_class->as()]; - if(ti->base != tp_object) { - PyTypeInfo* base_ti = &_all_types[ti->base]; - if(base_ti->on_end_subclass) base_ti->on_end_subclass(this, ti); - } - __curr_class = nullptr; - } - DISPATCH() - case OP_STORE_CLASS_ATTR: { - assert(__curr_class != nullptr); - StrName _name(byte.arg); - PyVar _0 = POPX(); - if(is_type(_0, tp_function)) { PK_OBJ_GET(Function, _0)._class = __curr_class; } - __curr_class->attr().set(_name, _0); - } - DISPATCH() - case OP_BEGIN_CLASS_DECORATION: { - PUSH(__curr_class); - } - DISPATCH() - case OP_END_CLASS_DECORATION: { - __curr_class = POPX().get(); - } - DISPATCH() - case OP_ADD_CLASS_ANNOTATION: { - assert(__curr_class != nullptr); - StrName _name(byte.arg); - Type type = __curr_class->as(); - _all_types[type].annotated_fields.push_back(_name); - } - DISPATCH() - /*****************************************/ - case OP_WITH_ENTER: PUSH(call_method(TOP(), __enter__)); DISPATCH() - case OP_WITH_EXIT: - call_method(TOP(), __exit__); - POP(); - DISPATCH() - /*****************************************/ - case OP_TRY_ENTER: { - frame->set_unwind_target(s_data.sp); - DISPATCH() - } - case OP_EXCEPTION_MATCH: { - PyVar assumed_type = POPX(); - check_type(assumed_type, tp_type); - PyVar e_obj = TOP(); - bool ok = isinstance(e_obj, PK_OBJ_GET(Type, assumed_type)); - PUSH(VAR(ok)); - } - DISPATCH() - case OP_RAISE: { - if(is_type(TOP(), tp_type)) { TOP() = call(TOP()); } - if(!isinstance(TOP(), tp_exception)) { TypeError("exceptions must derive from Exception"); } - _error(POPX()); - } - DISPATCH() - case OP_RAISE_ASSERT: - if(byte.arg) { - Str msg = py_str(TOP()); - POP(); - AssertionError(msg); - } else { - AssertionError(); - } - DISPATCH() - case OP_RE_RAISE: __raise_exc(true); DISPATCH() - case OP_POP_EXCEPTION: __last_exception = POPX().get(); DISPATCH() - /*****************************************/ - case OP_FORMAT_STRING: { - PyVar _0 = POPX(); - const Str& spec = CAST(Str&, c11__getitem(PyVar, &frame->co->consts, byte.arg)); - PUSH(__format_object(_0, spec)); - } - DISPATCH() - /*****************************************/ - default: PK_UNREACHABLE() - } - } - /**********************************************************************/ - PK_UNREACHABLE() - } catch(InternalException internal) { - __internal_exception = internal; - if(internal.type == InternalExceptionType::Unhandled) { - __last_exception = POPX().get(); - Exception& _e = __last_exception->as(); - bool is_base_frame_to_be_popped = frame == base_frame; - __pop_frame(); - if(callstack.empty()) { - // propagate to the top level - throw TopLevelException(this, &_e); - } - frame = &callstack.top(); - PUSH(__last_exception); - if(is_base_frame_to_be_popped) { throw InternalException(InternalExceptionType::ToBeRaised); } - } - } - } -} +// case OP_IS_OP: { +// PyVar _1 = POPX(); // rhs +// PyVar _0 = TOP(); // lhs +// TOP() = PyVar__IS_OP(&_0, &_1) ? True : False; +// } +// DISPATCH() +// case OP_IS_NOT_OP: { +// PyVar _1 = POPX(); // rhs +// PyVar _0 = TOP(); // lhs +// TOP() = PyVar__IS_OP(&_0, &_1) ? False : True; +// } +// DISPATCH() +// case OP_CONTAINS_OP: { +// // a in b -> b __contains__ a +// auto _ti = _tp_info(TOP()); +// PyVar _0; +// if(_ti->m__contains__) { +// _0 = _ti->m__contains__(this, TOP(), SECOND()); +// } else { +// _0 = call_method(TOP(), __contains__, SECOND()); +// } +// POP(); +// TOP() = VAR(static_cast((int)CAST(bool, _0) ^ byte.arg)); +// } +// DISPATCH() +// /*****************************************/ +// case OP_JUMP_FORWARD: DISPATCH_JUMP((int16_t)byte.arg) +// case OP_POP_JUMP_IF_FALSE: +// if(!py_bool(POPX())) DISPATCH_JUMP((int16_t)byte.arg) +// DISPATCH() +// case OP_POP_JUMP_IF_TRUE: +// if(py_bool(POPX())) DISPATCH_JUMP((int16_t)byte.arg) +// DISPATCH() +// case OP_JUMP_IF_TRUE_OR_POP: +// if(py_bool(TOP())) { +// DISPATCH_JUMP((int16_t)byte.arg) +// } else { +// POP(); +// DISPATCH() +// } +// case OP_JUMP_IF_FALSE_OR_POP: +// if(!py_bool(TOP())) { +// DISPATCH_JUMP((int16_t)byte.arg) +// } else { +// POP(); +// DISPATCH() +// } +// case OP_SHORTCUT_IF_FALSE_OR_POP: +// if(!py_bool(TOP())) { // [b, False] +// STACK_SHRINK(2); // [] +// PUSH(vm->False); // [False] +// DISPATCH_JUMP((int16_t)byte.arg) +// } else { +// POP(); // [b] +// DISPATCH() +// } +// case OP_LOOP_CONTINUE: +// // just an alias of OP_JUMP_FORWARD +// DISPATCH_JUMP((int16_t)byte.arg) +// case OP_LOOP_BREAK: { +// frame->prepare_jump_break(&s_data, frame->ip() + byte.arg); +// DISPATCH_JUMP((int16_t)byte.arg) +// } +// case OP_JUMP_ABSOLUTE_TOP: DISPATCH_JUMP_ABSOLUTE(_CAST(int, POPX())) +// case OP_GOTO: { +// StrName _name(byte.arg); +// int target = c11_smallmap_n2i__get(&frame->co->labels, byte.arg, -1); +// if(target < 0) RuntimeError(_S("label ", _name.escape(), " not found")); +// frame->prepare_jump_break(&s_data, target); +// DISPATCH_JUMP_ABSOLUTE(target) +// } +// /*****************************************/ +// case OP_FSTRING_EVAL: { +// PyVar _0 = c11__getitem(PyVar, &frame->co->consts, byte.arg); +// std::string_view string = CAST(Str&, _0).sv(); +// // TODO: optimize this +// CodeObject* code = vm->compile(string, "", EVAL_MODE, true); +// _0 = vm->_exec(code, frame->_module, frame->_callable, frame->_locals); +// CodeObject__delete(code); +// PUSH(_0); +// } +// DISPATCH() +// case OP_REPR: TOP() = VAR(py_repr(TOP())); DISPATCH() +// case OP_CALL: { +// pk_ManagedHeap__collect_if_needed(&heap); +// PyVar _0 = vectorcall(byte.arg & 0xFF, // ARGC +// (byte.arg >> 8) & 0xFF, // KWARGC +// true); +// if(_0.type == tp_op_call) { +// frame = &callstack.top(); +// goto __NEXT_FRAME; +// } +// PUSH(_0); +// } +// DISPATCH() +// case OP_CALL_TP: { +// pk_ManagedHeap__collect_if_needed(&heap); +// PyVar _0; +// PyVar _1; +// PyVar _2; +// // [callable, , args: tuple, kwargs: dict | NULL] +// if(byte.arg) { +// _2 = POPX(); +// _1 = POPX(); +// for(PyVar obj: _CAST(Tuple&, _1)) +// PUSH(obj); +// _CAST(Dict&, _2).apply([this](PyVar k, PyVar v) { +// PUSH(VAR(StrName(CAST(Str&, k)).index)); +// PUSH(v); +// }); +// _0 = vectorcall(_CAST(Tuple&, _1).size(), // ARGC +// _CAST(Dict&, _2).size(), // KWARGC +// true); +// } else { +// // no **kwargs +// _1 = POPX(); +// for(PyVar obj: _CAST(Tuple&, _1)) +// PUSH(obj); +// _0 = vectorcall(_CAST(Tuple&, _1).size(), // ARGC +// 0, // KWARGC +// true); +// } +// if(_0.type == tp_op_call) { +// frame = &callstack.top(); +// goto __NEXT_FRAME; +// } +// PUSH(_0); +// } +// DISPATCH() +// case OP_RETURN_VALUE: { +// PyVar _0 = byte.arg == BC_NOARG ? POPX() : None; +// __pop_frame(); +// if(frame == base_frame) { // [ frameBase<- ] +// return _0; +// } else { +// frame = &callstack.top(); +// PUSH(_0); +// goto __NEXT_FRAME; +// } +// } +// DISPATCH() +// case OP_YIELD_VALUE: return PY_OP_YIELD; +// /*****************************************/ +// case OP_LIST_APPEND: { +// PyVar _0 = POPX(); +// PK_OBJ_GET(List, SECOND()).push_back(_0); +// } +// DISPATCH() +// case OP_DICT_ADD: { +// PyVar _0 = POPX(); +// const Tuple& t = PK_OBJ_GET(Tuple, _0); +// PK_OBJ_GET(Dict, SECOND()).set(this, t[0], t[1]); +// } +// DISPATCH() +// case OP_SET_ADD: { +// PyVar _0 = POPX(); +// call_method(SECOND(), pk_id_add, _0); +// } +// DISPATCH() +// /*****************************************/ +// case OP_UNARY_NEGATIVE: TOP() = py_negate(TOP()); DISPATCH() +// case OP_UNARY_NOT: TOP() = VAR(!py_bool(TOP())); DISPATCH() +// case OP_UNARY_STAR: TOP() = VAR(StarWrapper(byte.arg, TOP())); DISPATCH() +// case OP_UNARY_INVERT: { +// PyVar _0; +// auto _ti = _tp_info(TOP()); +// if(_ti->m__invert__) +// _0 = _ti->m__invert__(this, TOP()); +// else +// _0 = call_method(TOP(), __invert__); +// TOP() = _0; +// } +// DISPATCH() +// /*****************************************/ +// case OP_GET_ITER: TOP() = py_iter(TOP()); DISPATCH() +// case OP_GET_ITER_NEW: TOP() = py_iter(TOP()); DISPATCH() +// case OP_FOR_ITER: { +// PyVar _0 = py_next(TOP()); +// if(_0 == StopIteration) { +// int target = frame->prepare_loop_break(&s_data); +// DISPATCH_JUMP_ABSOLUTE(target) +// } else { +// PUSH(_0); +// DISPATCH() +// } +// } +// case OP_FOR_ITER_STORE_FAST: { +// PyVar _0 = py_next(TOP()); +// if(_0 == StopIteration) { +// int target = frame->prepare_loop_break(&s_data); +// DISPATCH_JUMP_ABSOLUTE(target) +// } else { +// frame->_locals[byte.arg] = _0; +// DISPATCH() +// } +// } +// case OP_FOR_ITER_STORE_GLOBAL: { +// PyVar _0 = py_next(TOP()); +// if(_0 == StopIteration) { +// int target = frame->prepare_loop_break(&s_data); +// DISPATCH_JUMP_ABSOLUTE(target) +// } else { +// frame->f_globals().set(StrName(byte.arg), _0); +// DISPATCH() +// } +// } +// case OP_FOR_ITER_YIELD_VALUE: { +// PyVar _0 = py_next(TOP()); +// if(_0 == StopIteration) { +// int target = frame->prepare_loop_break(&s_data); +// DISPATCH_JUMP_ABSOLUTE(target) +// } else { +// PUSH(_0); +// return PY_OP_YIELD; +// } +// } +// case OP_FOR_ITER_UNPACK: { +// PyVar _0 = TOP(); +// const PyTypeInfo* _ti = _tp_info(_0); +// if(_ti->op__next__) { +// unsigned n = _ti->op__next__(this, _0); +// if(n == 0) { +// // StopIteration +// int target = frame->prepare_loop_break(&s_data); +// DISPATCH_JUMP_ABSOLUTE(target) +// } else if(n == 1) { +// // UNPACK_SEQUENCE +// __op_unpack_sequence(byte.arg); +// } else { +// if(n != byte.arg) { +// ValueError(_S("expected ", (int)byte.arg, " values to unpack, got ", (int)n)); +// } +// } +// } else { +// // FOR_ITER +// _0 = call_method(_0, __next__); +// if(_0 != StopIteration) { +// PUSH(_0); +// // UNPACK_SEQUENCE +// __op_unpack_sequence(byte.arg); +// } else { +// int target = frame->prepare_loop_break(&s_data); +// DISPATCH_JUMP_ABSOLUTE(target) +// } +// } +// } +// DISPATCH() +// /*****************************************/ +// case OP_IMPORT_PATH: { +// PyVar _0 = c11__getitem(PyVar, &frame->co->consts, byte.arg); +// PUSH(py_import(CAST(Str&, _0))); +// } +// DISPATCH() +// case OP_POP_IMPORT_STAR: { +// PyVar _0 = POPX(); // pop the module +// PyVar _1 = _0->attr().try_get(__all__); +// StrName _name; +// if(_1 != nullptr) { +// for(PyVar key: CAST(List&, _1)) { +// _name = StrName::get(CAST(Str&, key).sv()); +// PyVar value = _0->attr().try_get_likely_found(_name); +// if(value == nullptr) { +// ImportError(_S("cannot import name ", _name.escape())); +// } else { +// frame->f_globals().set(_name, value); +// } +// } +// } else { +// for(auto& [name, value]: _0->attr().items()) { +// std::string_view s = name.sv(); +// if(s.empty() || s[0] == '_') continue; +// frame->f_globals().set(name, value); +// } +// } +// } +// DISPATCH() +// /*****************************************/ +// case OP_UNPACK_SEQUENCE: { +// __op_unpack_sequence(byte.arg); +// } +// DISPATCH() +// case OP_UNPACK_EX: { +// auto _lock = gc_scope_lock(); // lock the gc via RAII!! +// PyVar _0 = py_iter(POPX()); +// const PyTypeInfo* _ti = _tp_info(_0); +// PyVar _1; +// for(int i = 0; i < byte.arg; i++) { +// _1 = _py_next(_ti, _0); +// if(_1 == StopIteration) ValueError("not enough values to unpack"); +// PUSH(_1); +// } +// List extras; +// while(true) { +// _1 = _py_next(_ti, _0); +// if(_1 == StopIteration) break; +// extras.push_back(_1); +// } +// PUSH(VAR(std::move(extras))); +// } +// DISPATCH() +// /*****************************************/ +// case OP_BEGIN_CLASS: { +// StrName _name(byte.arg); +// PyVar _0 = POPX(); // super +// if(is_none(_0)) _0 = _t(tp_object); +// check_type(_0, tp_type); +// __curr_class = new_type_object(frame->_module, _name, PK_OBJ_GET(Type, _0), true); +// } +// DISPATCH() +// case OP_END_CLASS: { +// assert(__curr_class != nullptr); +// StrName _name(byte.arg); +// frame->_module->attr().set(_name, __curr_class); +// // call on_end_subclass +// PyTypeInfo* ti = &_all_types[__curr_class->as()]; +// if(ti->base != tp_object) { +// PyTypeInfo* base_ti = &_all_types[ti->base]; +// if(base_ti->on_end_subclass) base_ti->on_end_subclass(this, ti); +// } +// __curr_class = nullptr; +// } +// DISPATCH() +// case OP_STORE_CLASS_ATTR: { +// assert(__curr_class != nullptr); +// StrName _name(byte.arg); +// PyVar _0 = POPX(); +// if(is_type(_0, tp_function)) { PK_OBJ_GET(Function, _0)._class = __curr_class; } +// __curr_class->attr().set(_name, _0); +// } +// DISPATCH() +// case OP_BEGIN_CLASS_DECORATION: { +// PUSH(__curr_class); +// } +// DISPATCH() +// case OP_END_CLASS_DECORATION: { +// __curr_class = POPX().get(); +// } +// DISPATCH() +// case OP_ADD_CLASS_ANNOTATION: { +// assert(__curr_class != nullptr); +// StrName _name(byte.arg); +// Type type = __curr_class->as(); +// _all_types[type].annotated_fields.push_back(_name); +// } +// DISPATCH() +// /*****************************************/ +// case OP_WITH_ENTER: PUSH(call_method(TOP(), __enter__)); DISPATCH() +// case OP_WITH_EXIT: +// call_method(TOP(), __exit__); +// POP(); +// DISPATCH() +// /*****************************************/ +// case OP_TRY_ENTER: { +// frame->set_unwind_target(s_data.sp); +// DISPATCH() +// } +// case OP_EXCEPTION_MATCH: { +// PyVar assumed_type = POPX(); +// check_type(assumed_type, tp_type); +// PyVar e_obj = TOP(); +// bool ok = isinstance(e_obj, PK_OBJ_GET(Type, assumed_type)); +// PUSH(VAR(ok)); +// } +// DISPATCH() +// case OP_RAISE: { +// if(is_type(TOP(), tp_type)) { TOP() = call(TOP()); } +// if(!isinstance(TOP(), tp_exception)) { TypeError("exceptions must derive from Exception"); } +// _error(POPX()); +// } +// DISPATCH() +// case OP_RAISE_ASSERT: +// if(byte.arg) { +// Str msg = py_str(TOP()); +// POP(); +// AssertionError(msg); +// } else { +// AssertionError(); +// } +// DISPATCH() +// case OP_RE_RAISE: __raise_exc(true); DISPATCH() +// case OP_POP_EXCEPTION: __last_exception = POPX().get(); DISPATCH() +// /*****************************************/ +// case OP_FORMAT_STRING: { +// PyVar _0 = POPX(); +// const Str& spec = CAST(Str&, c11__getitem(PyVar, &frame->co->consts, byte.arg)); +// PUSH(__format_object(_0, spec)); +// } +// DISPATCH() +// /*****************************************/ +// default: PK_UNREACHABLE() +// } +// } +// /**********************************************************************/ +// PK_UNREACHABLE() +// } catch(InternalException internal) { +// __internal_exception = internal; +// if(internal.type == InternalExceptionType::Unhandled) { +// __last_exception = POPX().get(); +// Exception& _e = __last_exception->as(); +// bool is_base_frame_to_be_popped = frame == base_frame; +// __pop_frame(); +// if(callstack.empty()) { +// // propagate to the top level +// throw TopLevelException(this, &_e); +// } +// frame = &callstack.top(); +// PUSH(__last_exception); +// if(is_base_frame_to_be_popped) { throw InternalException(InternalExceptionType::ToBeRaised); } +// } +// } +// } +// } -#undef TOP -#undef SECOND -#undef THIRD -#undef STACK_SHRINK -#undef PUSH -#undef POP -#undef POPX -#undef STACK_VIEW +// #undef TOP +// #undef SECOND +// #undef THIRD +// #undef STACK_SHRINK +// #undef PUSH +// #undef POP +// #undef POPX +// #undef STACK_VIEW -#undef DISPATCH -#undef DISPATCH_JUMP -#undef CEVAL_STEP_CALLBACK +// #undef DISPATCH +// #undef DISPATCH_JUMP +// #undef CEVAL_STEP_CALLBACK -} // namespace pkpy +// } // namespace pkpy diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index 7ae144d2..28714691 100644 --- a/src/interpreter/frame.c +++ b/src/interpreter/frame.c @@ -40,7 +40,7 @@ void UnwindTarget__delete(UnwindTarget* self){ } Frame* Frame__new(Frame* f_back, const CodeObject* co, PyObject* module_, PyObject* function, PyVar* p0, PyVar* locals, const CodeObject* locals_co){ - static_assert(sizeof(Frame) <= kPoolFrameBlockSize); + static_assert(sizeof(Frame) <= kPoolFrameBlockSize, "!(sizeof(Frame) <= kPoolFrameBlockSize)"); Frame* self = PoolFrame_alloc(); self->f_back = f_back; self->ip = (Bytecode*)co->codes.data - 1; diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index b787718d..be77f0c4 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -6,10 +6,12 @@ static unsigned char* pk_default_import_file(pk_VM* vm, const char* path){ static void pk_default_stdout(pk_VM* vm, const char* s){ fprintf(stdout, "%s", s); + fflush(stdout); } static void pk_default_stderr(pk_VM* vm, const char* s){ fprintf(stderr, "%s", s); + fflush(stderr); } void pk_TypeInfo__ctor(pk_TypeInfo *self, StrName name, Type base, PyObject* obj, PyObject* module, bool subclass_enabled){ @@ -70,7 +72,7 @@ void pk_VM__ctor(pk_VM* self){ /* Init Builtin Types */ // 0: unused - pk_TypeInfo__ctor(c11_vector__emplace(&self->types), 0, 0, NULL, NULL); + pk_TypeInfo__ctor(c11_vector__emplace(&self->types), 0, 0, NULL, NULL, false); #define validate(t, expr) if(t != (expr)) abort() validate(tp_object, pk_VM__new_type(self, "object", 0, NULL, true)); diff --git a/src/objects/dict.c b/src/objects/dict.c index 65f9de98..8dfe376b 100644 --- a/src/objects/dict.c +++ b/src/objects/dict.c @@ -3,7 +3,6 @@ #include #include #include -#include "pocketpy/objects/public.h" #define DICT_MAX_LOAD 0.75 #define DICT_HASH_NEXT(h) ((h) * 5 + 1)