blueloveTH 2 лет назад
Родитель
Сommit
d0453ab15f
2 измененных файлов с 40 добавлено и 25 удалено
  1. 24 13
      src/ceval.h
  2. 16 12
      src/expr.h

+ 24 - 13
src/ceval.h

@@ -470,19 +470,30 @@ __NEXT_STEP:;
         PUSH(_0);
         DISPATCH();
     TARGET(CALL_TP)
-        // [callable, <self>, args: tuple, kwargs: dict]
-        _2 = POPX();
-        _1 = POPX();
-        for(PyObject* obj: _CAST(Tuple&, _1)) PUSH(obj);
-        _CAST(Dict&, _2).apply([this](PyObject* k, PyObject* v){
-            PUSH(VAR(StrName(CAST(Str&, k)).index));
-            PUSH(v);
-        });
-        _0 = vectorcall(
-            _CAST(Tuple&, _1).size(),   // ARGC
-            _CAST(Dict&, _2).size(),    // KWARGC
-            true
-        );
+        // [callable, <self>, args: tuple, kwargs: dict | NULL]
+        if(byte.arg){
+            _2 = POPX();
+            _1 = POPX();
+            for(PyObject* obj: _CAST(Tuple&, _1)) PUSH(obj);
+            _CAST(Dict&, _2).apply([this](PyObject* k, PyObject* v){
+                PUSH(VAR(StrName(CAST(Str&, k)).index));
+                PUSH(v);
+            });
+            _0 = vectorcall(
+                _CAST(Tuple&, _1).size(),   // ARGC
+                _CAST(Dict&, _2).size(),    // KWARGC
+                true
+            );
+        }else{
+            // no **kwargs
+            _1 = POPX();
+            for(PyObject* obj: _CAST(Tuple&, _1)) PUSH(obj);
+            _0 = vectorcall(
+                _CAST(Tuple&, _1).size(),   // ARGC
+                0,                          // KWARGC
+                true
+            );
+        }
         if(_0 == PY_OP_CALL) DISPATCH_OP_CALL();
         PUSH(_0);
         DISPATCH();

+ 16 - 12
src/expr.h

@@ -686,20 +686,24 @@ struct CallExpr: Expr{
             for(auto& item: args) item->emit(ctx);
             ctx->emit(OP_BUILD_TUPLE_UNPACK, (int)args.size(), line);
 
-            for(auto& item: kwargs){
-                if(item.second->is_starred()){
-                    if(item.second->star_level() != 2) FATAL_ERROR();
-                    item.second->emit(ctx);
-                }else{
-                    // k=v
-                    int index = ctx->add_const(py_var(ctx->vm, item.first));
-                    ctx->emit(OP_LOAD_CONST, index, line);
-                    item.second->emit(ctx);
-                    ctx->emit(OP_BUILD_TUPLE, 2, line);
+            if(!kwargs.empty()){
+                for(auto& item: kwargs){
+                    if(item.second->is_starred()){
+                        if(item.second->star_level() != 2) FATAL_ERROR();
+                        item.second->emit(ctx);
+                    }else{
+                        // k=v
+                        int index = ctx->add_const(py_var(ctx->vm, item.first));
+                        ctx->emit(OP_LOAD_CONST, index, line);
+                        item.second->emit(ctx);
+                        ctx->emit(OP_BUILD_TUPLE, 2, line);
+                    }
                 }
+                ctx->emit(OP_BUILD_DICT_UNPACK, (int)kwargs.size(), line);
+                ctx->emit(OP_CALL_TP, 1, line);
+            }else{
+                ctx->emit(OP_CALL_TP, 0, line);
             }
-            ctx->emit(OP_BUILD_DICT_UNPACK, (int)kwargs.size(), line);
-            ctx->emit(OP_CALL_TP, BC_NOARG, line);
         }else{
             // vectorcall protocal
             for(auto& item: args) item->emit(ctx);