Browse Source

Update vm.h

Update vm.h
blueloveTH 2 years ago
parent
commit
e936f349a0
1 changed files with 18 additions and 16 deletions
  1. 18 16
      src/vm.h

+ 18 - 16
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<DummyInstance>(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<DummyInstance>(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){