From e936f349a0f1420a629f176e4f09919e15400d0d Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sun, 9 Apr 2023 18:21:13 +0800 Subject: [PATCH] Update vm.h Update vm.h --- src/vm.h | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/vm.h b/src/vm.h index 32333960..e00aa69a 100644 --- a/src/vm.h +++ b/src/vm.h @@ -674,21 +674,6 @@ inline void VM::init_builtin_types(){ // TODO: callable/args here may be garbage collected accidentally inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, bool opCall){ - if(is_type(callable, tp_type)){ - PyObject* new_f = callable->attr().try_get(__new__); - PyObject* obj; - if(new_f != nullptr){ - obj = call(new_f, std::move(args), kwargs, false); - }else{ - obj = heap.gcnew(OBJ_GET(Type, callable), {}); - PyObject* self; - PyObject* init_f = get_unbound_method(obj, __init__, &self, false); - args.extend_self(self); - if (self != _py_null) call(init_f, std::move(args), kwargs, false); - } - return obj; - } - if(is_type(callable, tp_bound_method)){ auto& bm = CAST(BoundMethod&, callable); callable = bm.method; // get unbound method @@ -716,7 +701,9 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo TypeError(fmt("missing positional argument ", name.escape())); } - locals->update(fn.decl->kwargs); + // NameDict.update is of O(capacity) complexity + // so we try not to call it if possible + if(fn.decl->kwargs.size()!=0) locals->update(fn.decl->kwargs); if(!fn.decl->starred_arg.empty()){ List vargs; // handle *args @@ -748,6 +735,21 @@ inline PyObject* VM::call(PyObject* callable, Args args, const Args& kwargs, boo return _exec(); } + if(is_type(callable, tp_type)){ + PyObject* new_f = callable->attr().try_get(__new__); + PyObject* obj; + if(new_f != nullptr){ + obj = call(new_f, std::move(args), kwargs, false); + }else{ + obj = heap.gcnew(OBJ_GET(Type, callable), {}); + PyObject* self; + PyObject* init_f = get_unbound_method(obj, __init__, &self, false); + args.extend_self(self); + if (self != _py_null) call(init_f, std::move(args), kwargs, false); + } + return obj; + } + PyObject* self; PyObject* call_f = get_unbound_method(callable, __call__, &self, false); if(self != _py_null){