This commit is contained in:
blueloveTH 2023-04-18 18:41:57 +08:00
parent 1d20da3891
commit d828fcfecc
3 changed files with 8 additions and 7 deletions

View File

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

View File

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

View File

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