diff --git a/src/ceval.h b/src/ceval.h index 5fd78a24..7e2e1482 100644 --- a/src/ceval.h +++ b/src/ceval.h @@ -21,6 +21,7 @@ inline PyObject* VM::_run_top_frame(){ #endif try{ if(need_raise){ need_raise = false; _raise(); } + if(s_data.is_overflow()) StackOverflowError(); /**********************************************************************/ /* NOTE: * Be aware of accidental gc! @@ -52,7 +53,7 @@ goto *OP_LABELS[byte.op]; __NEXT_STEP:; #if DEBUG_CEVAL_STEP - std::cout << frame->stack_info() << " " << OP_NAMES[byte.op] << std::endl; + _log_s_data(); #endif #if DEBUG_CEVAL_STEP_MIN std::cout << OP_NAMES[byte.op] << std::endl; @@ -495,7 +496,6 @@ __NEXT_STEP:; obj = iter->next(); while(obj != nullptr){ PUSH(obj); - // if(s_data.is_overflow()) StackOverflowError(); obj = iter->next(); } } DISPATCH(); diff --git a/src/common.h b/src/common.h index 268ec0a4..91569109 100644 --- a/src/common.h +++ b/src/common.h @@ -34,7 +34,7 @@ // debug macros #define DEBUG_NO_BUILTIN_MODULES 0 #define DEBUG_EXTRA_CHECK 1 -#define DEBUG_DIS_EXEC 1 +#define DEBUG_DIS_EXEC 0 #define DEBUG_CEVAL_STEP 0 #define DEBUG_CEVAL_STEP_MIN 0 #define DEBUG_FULL_EXCEPTION 1 @@ -53,8 +53,13 @@ #define PK_ENABLE_COMPUTED_GOTO 0 #define UNREACHABLE() __assume(0) #else -#define PK_ENABLE_COMPUTED_GOTO 0 +#define PK_ENABLE_COMPUTED_GOTO 1 #define UNREACHABLE() __builtin_unreachable() + +#if DEBUG_CEVAL_STEP || DEBUG_CEVAL_STEP_MIN +#undef PK_ENABLE_COMPUTED_GOTO +#endif + #endif #if defined(__EMSCRIPTEN__) || defined(__arm__) || defined(__i386__) diff --git a/src/frame.h b/src/frame.h index d7ae9130..487f1dc6 100644 --- a/src/frame.h +++ b/src/frame.h @@ -158,15 +158,6 @@ struct ValueStack { void clear() { _sp = _begin; } bool is_overflow() const { return _sp >= _begin + MAX_SIZE; } - void dup_top_n(int n) { - // [a, b, c] - // ^p0 ^p1 - PyObject** p0 = _sp - n; - PyObject** p1 = _sp; - memcpy(p1, p0, n * sizeof(void*)); - _sp += n; - } - ValueStack(const ValueStack&) = delete; ValueStack(ValueStack&&) = delete; ValueStack& operator=(const ValueStack&) = delete; @@ -211,22 +202,10 @@ struct Frame { } int stack_size() const { return _s->_sp - _sp_base; } - ArgsView stack_view() const { return ArgsView(_sp_base, _s->_sp); } - std::string stack_info(){ - std::stringstream ss; - ss << this << ": ["; - for(PyObject** t=_sp_base; t<_s->end(); t++){ - ss << *t; - if(t != _s->end()-1) ss << ", "; - } - ss << "]"; - return ss.str(); - } - void jump_abs(int i){ _next_ip = i; } - void jump_rel(int i){ _next_ip += i; } + // void jump_rel(int i){ _next_ip += i; } bool jump_to_exception_handler(){ // try to find a parent try block diff --git a/src/vm.h b/src/vm.h index c79d8c08..580d863d 100644 --- a/src/vm.h +++ b/src/vm.h @@ -323,7 +323,6 @@ public: else throw UnhandledException(); } - void RecursionError() { _error("RecursionError", "maximum recursion depth exceeded"); } void StackOverflowError() { _error("StackOverflowError", ""); } void IOError(const Str& msg) { _error("IOError", msg); } void NotImplementedError(){ _error("NotImplementedError", ""); } @@ -363,8 +362,8 @@ public: _lazy_modules.clear(); } + void _log_s_data(const char* title = nullptr); PyObject* _vectorcall(int ARGC, int KWARGC=0, bool op_call=false); - CodeObject_ compile(Str source, Str filename, CompileMode mode, bool unknown_global_scope=false); PyObject* num_negated(PyObject* obj); f64 num_to_float(PyObject* obj); @@ -546,9 +545,7 @@ inline bool VM::asBool(PyObject* obj){ PyObject* self; PyObject* len_f = get_unbound_method(obj, __len__, &self, false); if(self != _py_null){ - PUSH(len_f); - PUSH(self); - PyObject* ret = _vectorcall(0); + PyObject* ret = call_method(self, len_f); return CAST(i64, ret) > 0; } return true; @@ -657,6 +654,28 @@ inline Str VM::disassemble(CodeObject_ co){ return Str(ss.str()); } +inline void VM::_log_s_data(const char* title) { + std::stringstream ss; + if(title) ss << title << " | "; + FrameId frame = top_frame(); + ss << frame->co->name << ": ["; + for(PyObject* obj: s_data){ + if(obj == _py_begin_call) ss << "BEGIN_CALL"; + else if(obj == _py_null) ss << "NULL"; + else if(is_int(obj)) ss << CAST(i64, obj); + else if(is_float(obj)) ss << CAST(f64, obj); + else ss << obj << "(" << obj_type_name(this, obj->type) << ")"; + ss << ", "; + } + std::string output = ss.str(); + if(!s_data.empty()) { + output.pop_back(); output.pop_back(); + } + output.push_back(']'); + Bytecode byte = frame->co->codes[frame->_ip]; + std::cout << output << " " << OP_NAMES[byte.op] << std::endl; +} + inline void VM::init_builtin_types(){ _all_types.push_back({heap._new(Type(1), Type(0)), -1, "object"}); _all_types.push_back({heap._new(Type(1), Type(1)), 0, "type"}); @@ -770,8 +789,11 @@ inline PyObject* VM::_vectorcall(int ARGC, int KWARGC, bool op_call){ PyObject* obj; if(new_f != nullptr){ PUSH(new_f); - s_data.dup_top_n(1 + ARGC + KWARGC*2); - obj = _vectorcall(ARGC, KWARGC, false); + PUSH(_py_null); + for(PyObject* obj: args) PUSH(obj); + for(PyObject* obj: kwargs) PUSH(obj); + // _log_s_data("L790"); + obj = _vectorcall(ARGC, KWARGC); if(!isinstance(obj, OBJ_GET(Type, callable))) return obj; }else{ obj = heap.gcnew(OBJ_GET(Type, callable), {}); @@ -783,7 +805,7 @@ inline PyObject* VM::_vectorcall(int ARGC, int KWARGC, bool op_call){ p1[-(ARGC + 2)] = callable; p1[-(ARGC + 1)] = self; // [init_f, self, args..., kwargs...] - _vectorcall(ARGC, KWARGC, false); + _vectorcall(ARGC, KWARGC); // We just discard the return value of `__init__` // in cpython it raises a TypeError if the return value is not None }else{