From d828fcfecc3cdf8a9ce09a11a0c6a07e1c8f9d82 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 18 Apr 2023 18:41:57 +0800 Subject: [PATCH] ... --- src/ceval.h | 5 +++-- src/obj.h | 2 +- src/vm.h | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ceval.h b/src/ceval.h index 81418970..4b1238b2 100644 --- a/src/ceval.h +++ b/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(); diff --git a/src/obj.h b/src/obj.h index 4071d655..74d609f8 100644 --- a/src/obj.h +++ b/src/obj.h @@ -34,13 +34,13 @@ struct FuncDecl { pod_vector 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; struct Function{ FuncDecl_ decl; + bool is_simple; PyObject* _module; NameDict_ _closure; }; diff --git a/src/vm.h b/src/vm.h index b5b4e3a2..74dc82fc 100644 --- a/src/vm.h +++ b/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