blueloveTH 2 лет назад
Родитель
Сommit
bb93dd54dd
3 измененных файлов с 57 добавлено и 61 удалено
  1. 53 6
      src/ceval.h
  2. 1 1
      src/iter.h
  3. 3 54
      src/vm.h

+ 53 - 6
src/ceval.h

@@ -5,9 +5,21 @@
 
 namespace pkpy{
 
-#define DISPATCH() goto __NEXT_STEP
+inline PyObject* VM::_run_top_frame(){
+    FrameId frame = top_frame();
+    const int base_id = frame.index;
+    bool need_raise = false;
+    PyObject* __ret;
 
-inline PyObject* VM::run_frame(FrameId frame){
+    while(true){
+#if DEBUG_EXTRA_CHECK
+        if(frame->id < base_id) UNREACHABLE();
+#endif
+        try{
+            if(need_raise){ need_raise = false; _raise(); }
+/**********************************************************************/
+#define DISPATCH() goto __NEXT_STEP
+{
 __NEXT_STEP:;
     /* NOTE: 
     * Be aware of accidental gc!
@@ -284,7 +296,7 @@ __NEXT_STEP:;
         if(byte.op == OP_CALL_UNPACK) unpack_args(args);
         PyObject* callable = frame->popx();
         PyObject* ret = call(callable, std::move(args), no_arg(), true);
-        if(ret == _py_op_call) return ret;
+        if(ret == _py_op_call) { __ret=ret; goto __PY_OP_CALL; }
         frame->push(std::move(ret));
     } DISPATCH();
     case OP_CALL_KWARGS: case OP_CALL_KWARGS_UNPACK: {
@@ -300,10 +312,10 @@ __NEXT_STEP:;
         if(byte.op == OP_CALL_KWARGS_UNPACK) unpack_args(args);
         PyObject* callable = frame->popx();
         PyObject* ret = call(callable, std::move(args), kwargs, true);
-        if(ret == _py_op_call) return ret;
+        if(ret == _py_op_call) { __ret=ret; goto __PY_OP_CALL; }
         frame->push(std::move(ret));
     } DISPATCH();
-    case OP_RETURN_VALUE: return frame->popx();
+    case OP_RETURN_VALUE: { __ret=frame->popx(); goto __PY_SIMPLE_RETURN; }
     case OP_YIELD_VALUE: return _py_op_yield;
     /*****************************************/
     case OP_LIST_APPEND: {
@@ -456,7 +468,42 @@ __NEXT_STEP:;
     }
     UNREACHABLE();
 }
-
 #undef DISPATCH
+/**********************************************************************/
+__PY_SIMPLE_RETURN:
+            if(frame.index == base_id){       // [ frameBase<- ]
+                callstack.pop();
+                return __ret;
+            }else{
+                callstack.pop();
+                frame = top_frame();
+                frame->push(__ret);
+            }
+            continue;
+__PY_OP_CALL:
+            frame = top_frame();            // [ frameBase, newFrame<- ]
+            continue;
+        }catch(HandledException& e){
+            continue;
+        }catch(UnhandledException& e){
+            PyObject* obj = frame->popx();
+            Exception& _e = CAST(Exception&, obj);
+            _e.st_push(frame->snapshot());
+            callstack.pop();
+            if(callstack.empty()){
+#if DEBUG_FULL_EXCEPTION
+                std::cerr << _e.summary() << std::endl;
+#endif
+                throw _e;
+            }
+            frame = top_frame();
+            frame->push(obj);
+            if(frame.index < base_id) throw ToBeRaisedException();
+            need_raise = true;
+        }catch(ToBeRaisedException& e){
+            need_raise = true;
+        }
+    }
+}
 
 } // namespace pkpy

+ 1 - 1
src/iter.h

@@ -64,7 +64,7 @@ public:
 inline PyObject* Generator::next(){
     if(state == 2) return nullptr;
     vm->_push_new_frame(std::move(frame));
-    PyObject* ret = vm->_exec();
+    PyObject* ret = vm->_run_top_frame();
     if(ret == vm->_py_op_yield){
         frame = std::move(vm->callstack.top());
         vm->callstack.pop();

+ 3 - 54
src/vm.h

@@ -64,8 +64,6 @@ public:
     stack< Frame > callstack;
     std::vector<PyTypeInfo> _all_types;
 
-    PyObject* run_frame(FrameId frame);
-
     NameDict _modules;                                  // loaded modules
     std::map<StrName, Str> _lazy_modules;               // lazy loaded modules
 
@@ -206,7 +204,7 @@ public:
     template<typename ...Args>
     PyObject* _exec(Args&&... args){
         _push_new_frame(std::forward<Args>(args)...);
-        return _exec();
+        return _run_top_frame();
     }
 
     PyObject* property(NativeFuncRaw fget){
@@ -349,7 +347,7 @@ public:
     template<int ARGC>
     void bind_func(PyObject*, Str, NativeFuncRaw);
     void _error(Exception);
-    PyObject* _exec();
+    PyObject* _run_top_frame();
     void post_init();
 };
 
@@ -747,7 +745,7 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo
         }
         _push_new_frame(fn.decl->code, _module, locals, fn._closure);
         if(opCall) return _py_op_call;
-        return _exec();
+        return _run_top_frame();
     }
 
     if(is_type(callable, tp_type)){
@@ -906,55 +904,6 @@ inline void VM::_error(Exception e){
     _raise();
 }
 
-inline PyObject* VM::_exec(){
-    FrameId frame = top_frame();
-    const int base_id = frame.index;
-    bool need_raise = false;
-    PyObject* ret;
-
-    while(true){
-#if DEBUG_EXTRA_CHECK
-        if(frame->id < base_id) UNREACHABLE();
-#endif
-        try{
-            if(need_raise){ need_raise = false; _raise(); }
-            ret = run_frame(frame);
-            if(ret == _py_op_yield) return _py_op_yield;
-            if(ret != _py_op_call){
-                if(frame.index == base_id){       // [ frameBase<- ]
-                    callstack.pop();
-                    return ret;
-                }else{
-                    callstack.pop();
-                    frame = top_frame();
-                    frame->push(ret);
-                }
-            }else{
-                frame = top_frame();            // [ frameBase, newFrame<- ]
-            }
-        }catch(HandledException& e){
-            continue;
-        }catch(UnhandledException& e){
-            PyObject* obj = frame->popx();
-            Exception& _e = CAST(Exception&, obj);
-            _e.st_push(frame->snapshot());
-            callstack.pop();
-            if(callstack.empty()){
-#if DEBUG_FULL_EXCEPTION
-                std::cerr << _e.summary() << std::endl;
-#endif
-                throw _e;
-            }
-            frame = top_frame();
-            frame->push(obj);
-            if(frame.index < base_id) throw ToBeRaisedException();
-            need_raise = true;
-        }catch(ToBeRaisedException& e){
-            need_raise = true;
-        }
-    }
-}
-
 inline void ManagedHeap::mark() {
     for(PyObject* obj: _no_gc) OBJ_MARK(obj);
     for(auto& frame : vm->callstack.data()) frame._gc_mark();