blueloveTH 2 лет назад
Родитель
Сommit
d828fcfecc
3 измененных файлов с 8 добавлено и 7 удалено
  1. 3 2
      src/ceval.h
  2. 1 1
      src/obj.h
  3. 4 4
      src/vm.h

+ 3 - 2
src/ceval.h

@@ -83,11 +83,12 @@ __NEXT_STEP:;
     TARGET(LOAD_BUILTIN_EVAL) PUSH(builtins->attr(m_eval)); DISPATCH();
     TARGET(LOAD_FUNCTION) {
         FuncDecl_ decl = co->func_decls[byte.arg];
+        bool is_simple = decl->starred_arg==-1 && decl->kwargs.size()==0 && !decl->code->is_generator;
         PyObject* obj;
         if(decl->nested){
-            obj = VAR(Function({decl, frame->_module, frame->_locals.to_namedict()}));
+            obj = VAR(Function({decl, is_simple, frame->_module, frame->_locals.to_namedict()}));
         }else{
-            obj = VAR(Function({decl, frame->_module}));
+            obj = VAR(Function({decl, is_simple, frame->_module}));
         }
         PUSH(obj);
     } DISPATCH();

+ 1 - 1
src/obj.h

@@ -34,13 +34,13 @@ struct FuncDecl {
     pod_vector<KwArg> kwargs;   // indices in co->varnames
     bool nested = false;        // whether this function is nested
     void _gc_mark() const;
-    bool is_simple() const { return kwargs.empty() && starred_arg == -1; }
 };
 
 using FuncDecl_ = shared_ptr<FuncDecl>;
 
 struct Function{
     FuncDecl_ decl;
+    bool is_simple;
     PyObject* _module;
     NameDict_ _closure;
 };

+ 4 - 4
src/vm.h

@@ -875,7 +875,7 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args,
 
     const Function& fn = CAST(Function&, callable);
     const CodeObject* co = fn.decl->code.get();
-    PyObject* _module = fn._module != nullptr ? fn._module : top_frame()->_module;
+    PyObject* _module = fn._module != nullptr ? fn._module : callstack.top()._module;
 
     if(args.size() < fn.decl->args.size()){
         vm->TypeError(fmt(
@@ -887,9 +887,9 @@ inline PyObject* VM::_py_call(PyObject** p0, PyObject* callable, ArgsView args,
         ));
     }
 
-    // if this function is simple, a.k.a, no kwargs or *args
-    // we can avoid using buffer copy
-    if(fn.decl->is_simple() && !co->is_generator){
+    // if this function is simple, a.k.a, no kwargs and no *args and not a generator
+    // we can use a fast path to avoid using buffer copy
+    if(fn.is_simple){
 #if DEBUG_EXTRA_CHECK
         for(PyObject** p=p0; p<args.begin(); p++) *p = nullptr;
 #endif