blueloveTH 1 год назад
Родитель
Сommit
58c5bb1d35

+ 3 - 0
include/pocketpy/common/vector.h

@@ -88,6 +88,9 @@ void* c11_vector__emplace(c11_vector* self);
         } \
     }while(0)
 
+#define c11_vector__foreach(T, self, it) \
+    for(T* it = (T*)(self)->data; it != (T*)(self)->data + (self)->count; it++)
+
 #ifdef __cplusplus
 }
 #endif

+ 6 - 3
include/pocketpy/objects/codeobject.hpp

@@ -62,6 +62,7 @@ struct CodeObject {
 };
 
 struct FuncDecl {
+    PK_ALWAYS_PASS_BY_POINTER(FuncDecl)
     struct KwArg {
         int index;    // index in co->varnames
         StrName key;  // name of this argument
@@ -70,8 +71,8 @@ struct FuncDecl {
 
     CodeObject_ code;  // code object of this function
 
-    small_vector_2<int, 8> args;      // indices in co->varnames
-    small_vector_2<KwArg, 6> kwargs;  // indices in co->varnames
+    small_vector_2<int, 8> args;    // indices in co->varnames
+    c11_vector/*T=KwArg*/ kwargs;   // indices in co->varnames
 
     int starred_arg = -1;    // index in co->varnames, -1 if no *arg
     int starred_kwarg = -1;  // index in co->varnames, -1 if no **kwarg
@@ -84,16 +85,18 @@ struct FuncDecl {
 
     void add_kwarg(int index, StrName key, PyVar value) {
         c11_smallmap_n2i__set(&kw_to_index, key.index, index);
-        kwargs.push_back(KwArg{index, key, value});
+        c11_vector__push(KwArg, &kwargs, (KwArg{index, key.index, value}));
     }
 
     void _gc_mark(VM*) const;
 
     FuncDecl(){
+        c11_vector__ctor(&kwargs, sizeof(KwArg));
         c11_smallmap_n2i__ctor(&kw_to_index);
     }
 
     ~FuncDecl(){
+        c11_vector__dtor(&kwargs);
         c11_smallmap_n2i__dtor(&kw_to_index);
     }
 };

+ 3 - 3
src/compiler/compiler.cpp

@@ -84,7 +84,7 @@ Error* Compiler::pop_context() noexcept{
         }
         if(func->type == FuncType_UNSET) {
             bool is_simple = true;
-            if(func->kwargs.size() > 0) is_simple = false;
+            if(func->kwargs.count > 0) is_simple = false;
             if(func->starred_arg >= 0) is_simple = false;
             if(func->starred_kwarg >= 0) is_simple = false;
 
@@ -1165,8 +1165,8 @@ Error* Compiler::_compile_f_args(FuncDecl_ decl, bool enable_type_hints) noexcep
         for(int j: decl->args) {
             if(decl->code->varnames[j] == name) return SyntaxError("duplicate argument name");
         }
-        for(auto& kv: decl->kwargs) {
-            if(decl->code->varnames[kv.index] == name) return SyntaxError("duplicate argument name");
+        c11_vector__foreach(FuncDecl::KwArg, &decl->kwargs, kv) {
+            if(decl->code->varnames[kv->index] == name) return SyntaxError("duplicate argument name");
         }
         if(decl->starred_arg != -1 && decl->code->varnames[decl->starred_arg] == name) {
             return SyntaxError("duplicate argument name");

+ 8 - 6
src/interpreter/vm.cpp

@@ -996,8 +996,9 @@ void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const
     for(int index: decl->args)
         buffer[index] = args[i++];
     // prepare kwdefaults
-    for(auto& kv: decl->kwargs)
-        buffer[kv.index] = kv.value;
+    c11_vector__foreach(FuncDecl::KwArg, &decl->kwargs, kv) {
+        buffer[kv->index] = kv->value;
+    }
 
     // handle *args
     if(decl->starred_arg != -1) {
@@ -1006,9 +1007,9 @@ void VM::__prepare_py_call(PyVar* buffer, ArgsView args, ArgsView kwargs, const
         i += vargs.size();
     } else {
         // kwdefaults override
-        for(auto& kv: decl->kwargs) {
+        c11_vector__foreach(FuncDecl::KwArg, &decl->kwargs, kv) {
             if(i >= args.size()) break;
-            buffer[kv.index] = args[i++];
+            buffer[kv->index] = args[i++];
         }
         if(i < args.size()) TypeError(_S("too many arguments", " (", decl->code->name, ')'));
     }
@@ -1830,8 +1831,9 @@ void NativeFunc::_gc_mark(VM* vm) const {
 
 void FuncDecl::_gc_mark(VM* vm) const {
     code->_gc_mark(vm);
-    for(int i = 0; i < kwargs.size(); i++)
-        vm->obj_gc_mark(kwargs[i].value);
+    c11_vector__foreach(FuncDecl::KwArg, &kwargs, kv) {
+        vm->obj_gc_mark(kv->value);
+    }
 }
 
 void List::_gc_mark(VM* vm) const {