blueloveTH 2 سال پیش
والد
کامیت
ca78599049
4فایلهای تغییر یافته به همراه40 افزوده شده و 34 حذف شده
  1. 2 2
      src/ceval.h
  2. 7 2
      src/common.h
  3. 1 22
      src/frame.h
  4. 30 8
      src/vm.h

+ 2 - 2
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();

+ 7 - 2
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__)

+ 1 - 22
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

+ 30 - 8
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>(Type(1), Type(0)), -1, "object"});
     _all_types.push_back({heap._new<Type>(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<DummyInstance>(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{