Kaynağa Gözat

refactor: 去除gc_freeze函数

var_list使用提前添加tmp link的方式进行管理
SongZihuan 4 yıl önce
ebeveyn
işleme
ece0c1059d

+ 1 - 32
vmcore/gc/gc.c

@@ -10,13 +10,7 @@ static void gc_iterHashTable(HashTable *ht);
 #define resetGC(gcs) ((gcs)->continue_ = false, (gcs)->link = 0)
 
 // 若(gcs)->continue_为true, 则直接返回; 若为false则自增(+1后为false), 并返回自增前的值
-//#define gc_iterAlready(gcs) ((gcs)->continue_) || (((gcs)->continue_)++)  // TODO-szh 不能达到预期的效果
-
-static bool gc_iterAlready(GCStatus *gcs){
-    bool return_ = gcs->continue_;
-    gcs->continue_ = true;
-    return return_;
-}
+#define gc_iterAlready(gcs) (((gcs)->continue_) ? true : (((gcs)->continue_ = true), false))
 
 #define gc_needFree(gcs) ((gcs)->statement_link == 0 && (gcs)->tmp_link == 0 && (gcs)->link == 0)
 #define gc_resetValue(value) ((value)->gc_status.c_value = not_free)
@@ -212,29 +206,4 @@ void gc_run(Inter *inter, VarList *run_var, int var_list, int link_value, int va
     gc_freeBase(inter);
     gc_runDel(inter, run_var);
 }
-
-static void gc_freezeHashTable(HashTable *ht, bool is_lock){
-    if (ht == NULL)
-        return;
-
-    if (is_lock) {
-        gc_addTmpLink(&ht->gc_status);
-    } else {
-        gc_freeTmpLink(&ht->gc_status);
-    }
-
-    gc_iterAlready(&ht->gc_status);
-}
-
-/**
- * 冻结不可达的VarList的hashTable
- * @param inter
- * @param freeze
- * @param is_lock
- */
-void gc_freeze(Inter *inter, VarList *freeze, bool is_lock) {
-    gc_resetBase(inter);
-    for (PASS; freeze != NULL; freeze = freeze->next)
-        gc_freezeHashTable(freeze->hashtable, is_lock);
-}
 #endif

+ 1 - 0
vmcore/include/__virtualmath.h

@@ -26,6 +26,7 @@
 #if DEBUG
 /* DEBUG所使用的函数 */
 void printGC(Inter *inter);
+void printGCHS(Inter *inter);
 void printLinkValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link);
 void printValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link);
 void printVarGC(char *tag, Inter *inter);

+ 0 - 4
vmcore/include/gc.h

@@ -34,10 +34,7 @@ typedef struct GCStatus GCStatus;
 #define gc_freeTmpLink(gcs) ((gcs)->tmp_link --)
 #define gc_freeStatementLink(gcs) ((gcs)->statement_link --)
 #define setGC(gcs) ((gcs)->continue_ = false, (gcs)->link = 0, (gcs)->tmp_link = 0, (gcs)->statement_link = 0, (gcs)->c_value = not_free)
-
 void gc_runDelAll(struct Inter *inter);
-
-void gc_freeze(struct Inter *inter, struct VarList *freeze, bool is_lock);
 void gc_run(struct Inter *inter, struct VarList *run_var, int var_list, int link_value, int value, ...);
 #else
 #define gc_addTmpLink(gcs) ((void)0)
@@ -45,7 +42,6 @@ void gc_run(struct Inter *inter, struct VarList *run_var, int var_list, int link
 #define gc_addLink(gcs) ((void)0)
 #define gc_freeTmpLink(gcs) ((void)0)
 
-#define gc_freeze(...) ((void)0)
 #define gc_run(...) ((void)0)
 #define setGC(...) ((void)0)
 #define gc_freeStatementLink(gcs) ((void)0)

+ 3 - 3
vmcore/include/var.h

@@ -2,6 +2,8 @@
 #define VIRTUALMATH_VAR_H
 
 #define MAX_SIZE (8)
+#define copyVarListCore(base, inter) makeVarList((inter), false, (base)->hashtable)
+#define popVarList(base) (((base)->next == NULL) ? (base) : freeVarList(base))
 
 struct Var{
     GCStatus gc_status;
@@ -50,7 +52,7 @@ void freeVar(Var **var);
 HashTable *makeHashTable(Inter *inter);
 void freeHashTable(HashTable **value);
 
-VarList *makeVarList(Inter *inter, bool make_hash);
+VarList *makeVarList(Inter *inter, bool make_hash, HashTable *hs);
 VarList *freeVarList(VarList *vl);
 
 vhashn time33(wchar_t *key);
@@ -61,8 +63,6 @@ void updateHashTable(HashTable *update, HashTable *new, Inter *inter);
 void addFromVarList(wchar_t *name, LinkValue *name_, vint times, LinkValue *value, FUNC_CORE);
 
 VarList *pushVarList(VarList *base, Inter *inter);
-VarList *popVarList(VarList *base);
-VarList *copyVarListCore(VarList *base, Inter *inter);
 VarList *copyVarList(VarList *base, bool n_new, Inter *inter);
 VarList *connectVarListBack(VarList *base, VarList *back);
 VarList *makeObjectVarList(Inherit *value, Inter *inter, VarList *base);

+ 0 - 2
vmcore/ofunc/src/__ofunc.c

@@ -31,7 +31,6 @@ bool iterClassFunc(NameFunc *list, FUNC_NT){
     object_var->next = var_list;
     inter->data.default_pt_type = object_free_;
 
-    gc_freeze(inter, object_backup, true);
     for (PASS; list->of != NULL; list++) {
         LinkValue *value = registeredFunctionCore(list->of, list->name, CFUNC_NT(object_var, result, belong));
         if (!CHECK_RESULT(result)) {
@@ -41,7 +40,6 @@ bool iterClassFunc(NameFunc *list, FUNC_NT){
         value->value->data.function.function_data.pt_type = list->type;
         freeResult(result);
     }
-    gc_freeze(inter, object_backup, false);
 
     object_var->next = object_backup;
     inter->data.default_pt_type = bak;

+ 2 - 10
vmcore/ofunc/src/sys.c

@@ -173,7 +173,6 @@ ResultType vm_exec(O_FUNC){
     LinkValue *str;
     LinkValue *var;
     LinkValue *out;
-    bool out_;
     Statement *new_st;
     VarList *run;
 
@@ -204,7 +203,6 @@ ResultType vm_exec(O_FUNC){
             setResultError(E_TypeException, L"missing parameters: var", LINEFILE, true, CNEXT_NT);
             return R_error;
         }
-        out_ = out->value->data.bool_.bool_;
     } else
         out = false;
 
@@ -228,23 +226,17 @@ ResultType vm_exec(O_FUNC){
     }
 
     if (var != NULL) {
-        run = makeVarList(inter, false);
-        run->hashtable = var->value->data.dict.dict;
+        run = makeVarList(inter, false, var->value->data.dict.dict);
         if (out)
             run->next = var_list;
-        else
-            gc_freeze(inter, var_list, true);
     } else
         run = var_list;
 
     includeSafeInterStatement(CFUNC(new_st, run, result, belong));
     freeStatement(new_st);
 
-    if (var != NULL) {
-        if (!out)
-            gc_freeze(inter, var_list, false);
+    if (var != NULL)
         freeVarList(run);
-    }
 
     return result->type;
 }

+ 0 - 6
vmcore/src/__run.c

@@ -359,11 +359,9 @@ void addStrVar(wchar_t *name, bool free_old, bool setting, LinkValue *value, fli
 
 LinkValue *findAttributes(wchar_t *name, bool free_old, fline line, char *file, bool nowrun, FUNC_NT) {
     LinkValue *attr;
-    gc_freeze(inter, var_list, true);
     attr = findStrVar(name, free_old, line, file, nowrun, CFUNC_NT(belong->value->object.var, result, belong));
     if (attr != NULL && (attr->belong == NULL || attr->belong->value == belong->value || checkAttribution(belong->value, attr->belong->value)))
         attr->belong = belong;
-    gc_freeze(inter, var_list, false);
     return attr;
 }
 
@@ -382,11 +380,7 @@ bool addAttributes(wchar_t *name, bool free_old, LinkValue *value, fline line, c
     if (!CHECK_RESULT(result))
         goto return_;
     GET_RESULT(name_, result);
-
-    gc_freeze(inter, var_list, true);
     addStrVarCore(false, var_name, name_, line, file, var_list, CFUNC_NT(belong->value->object.var, result, value));
-    gc_freeze(inter, var_list, false);
-
     gc_freeTmpLink(&name_->gc_status);
 
     return_:

+ 28 - 14
vmcore/src/inter.c

@@ -10,7 +10,7 @@ Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong) {
     tmp->package = NULL;
 
     setBaseInterData(tmp);
-    tmp->var_list = makeVarList(tmp, true);
+    tmp->var_list = makeVarList(tmp, true, NULL);
 
     if (out != NULL) {
         tmp->data.inter_stdout = fopen(out, "w");
@@ -149,21 +149,30 @@ void freeInter(Inter *inter, bool show_gc) {
     gc_runDelAll(inter);
     freeBaseInterData(inter);
     freePackage(inter->package);
+    freeVarList(inter->var_list);
+
 #if DEBUG
     wint_t ch;
     if (show_gc && (printf("\nEnter '1' to show gc: "), (fgetwc(stdin)) == L'1')) {
         printGC(inter);
         while ((ch = fgetwc(stdin)) != '\n' || ch == WEOF)
             PASS;
-    }
+    } else
+        show_gc = false;
 #endif
-    freeVarList(inter->var_list);
+
     while (inter->base != NULL)
         freeValue(&inter->base);
     while (inter->base_var != NULL)
         freeVar(&inter->base_var);
     while (inter->link_base != NULL)
         freeLinkValue(&inter->link_base);
+
+#if DEBUG
+    if (show_gc)
+        printGCHS(inter);
+#endif
+
     while (inter->hash_base != NULL)
         freeHashTable(&inter->hash_base);
     memFree(inter);
@@ -219,24 +228,30 @@ void printGC(Inter *inter){
     long int lv_tmp = 0;
     long int v_st = 0;
     long int v_tmp = 0;
-    long int h_tmp = 0;
     printLinkValueGC("\n\nprintLinkValueGC TAG : freeInter", inter, &lv_tmp, &lv_st);
     printValueGC("\nprintValueGC TAG : freeInter", inter, &v_tmp, &v_st);
     printVarGC("\nprintVarGC TAG : freeInter", inter);
-    printHashTableGC("\nprintHashTableGC TAG : freeInter", inter, &h_tmp);
     printf("\n");
 
     printf("linkvalue tmp       link = %ld\n", lv_tmp);
     printf("linkvalue statement link = %ld\n", lv_st);
     printf("    value tmp       link = %ld\n", v_tmp);
     printf("    value statement link = %ld\n", v_st);
-    printf("hashtable tmp       link = %ld\n", h_tmp);
-    printf("      tmp link     count = %ld\n", lv_tmp + v_tmp + h_tmp);
+    printf("      tmp link     count = %ld\n", lv_tmp + v_tmp);
     printf("statement link     count = %ld\n", lv_st + v_st);
 #endif
 
 }
 
+void printGCHS(Inter *inter){  // 只输出hashtable
+#if START_GC
+    long int h_tmp = 0;
+    printHashTableGC("\nprintHashTableGC TAG : freeInter", inter, &h_tmp);
+    printf("\nhashtable tmp       link = %ld\n", h_tmp);
+#endif
+
+}
+
 #if START_GC
 void printLinkValueGC(char *tag, Inter *inter, long *tmp_link, long *st_link) {
     LinkValue *base = inter->link_base;
@@ -300,14 +315,13 @@ void printVarGC(char *tag, Inter *inter){
             printf("inter->link_base.tmp_link       = %ld :: %p\n", base->gc_status.tmp_link, base);
             printf("inter->link_base.statement_link = %ld :: %p\n", base->gc_status.statement_link, base);
             printf("inter->link_base.link           = %ld :: %p\n", base->gc_status.link, base);
+            printf("str_name = %ls\n", base->name);
+            printf("name = ");
+            printValue(base->name_->value, stdout, false, true);
+            printf("\nvalue = ");
+            printValue(base->value->value, stdout, false, true);
+            printf("\n-------------------------------------------\n");
         }
-
-        printf("str_name = %ls\n", base->name);
-        printf("name = ");
-        printValue(base->name_->value, stdout, false, true);
-        printf("\nvalue = ");
-        printValue(base->value->value, stdout, false, true);
-        printf("\n-------------------------------------------\n");
         base = base->gc_next;
     }
     printf("printVarGC TAG : END\n");

+ 2 - 8
vmcore/src/parameter.c

@@ -533,8 +533,6 @@ ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *f
     function = copyParameter(function_base);
     tmp_function = function;
     setResultCore(result);
-    gc_freeze(inter, function_var, true);
-    gc_freeze(inter, var_list, true);
 
     while (true){
         if (call == NULL && function == NULL)
@@ -578,7 +576,7 @@ ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *f
                 vint set_num = 0;
                 vint get_num = 0;
                 bool dict_status = false;
-                VarList *tmp = makeVarList(inter, true);
+                VarList *tmp = makeVarList(inter, true, NULL);
 
                 argumentToVar(&call, &set_num, CFUNC_NT(tmp, result, belong));
                 if (!CHECK_RESULT(result)) {
@@ -654,8 +652,6 @@ ResultType setParameterCore(fline line, char *file, Argument *call, Parameter *f
     setResult(result, inter);
 
     return_:
-    gc_freeze(inter, function_var, false);
-    gc_freeze(inter, var_list, false);
     freeParameter(tmp_function, true);
     return result->type;
 }
@@ -763,7 +759,6 @@ int parserNameArgument(ArgumentParser ap[], Argument *arg, ArgumentParser **bak,
     int return_;
     setResultCore(result);
 
-    gc_freeze(inter, var_list, true);
     for (PASS; arg != NULL && arg->type != name_arg; arg = arg->next)
         PASS;
     if (arg == NULL) {
@@ -771,7 +766,7 @@ int parserNameArgument(ArgumentParser ap[], Argument *arg, ArgumentParser **bak,
         goto return_;
     }
 
-    tmp = makeVarList(inter, true);
+    tmp = makeVarList(inter, true, NULL);
     argumentToVar(&arg, &set_num, CFUNC_NT(tmp, result, belong));
     if (!CHECK_RESULT(result)) {
         return_ = -1;
@@ -792,7 +787,6 @@ int parserNameArgument(ArgumentParser ap[], Argument *arg, ArgumentParser **bak,
 
     return_:
     freeVarList(tmp);
-    gc_freeze(inter, var_list, false);
     if (bak != NULL)
         *bak = ap;
     return return_;

+ 0 - 3
vmcore/src/runbranch.c

@@ -11,7 +11,6 @@ static bool checkNumber(FUNC){
 static void newBranchYield(Statement *branch_st, Statement *node, StatementList *sl_node, VarList *new_var, enum StatementInfoStatus status, Inter *inter){
     if (new_var != NULL)
         new_var->next = NULL;
-    gc_freeze(inter, new_var, true);
     branch_st->info.var_list = new_var;
     branch_st->info.node = node->type == yield_code ? node->next : node;
     branch_st->info.branch.sl_node = sl_node;
@@ -715,7 +714,6 @@ ResultType withBranch(FUNC) {
         }
     }
 
-    gc_freeze(inter, new, true);
     if (run_block) {
         if (vl_info == NULL)
             vl_info = with_list->code;
@@ -784,7 +782,6 @@ ResultType withBranch(FUNC) {
         result_from = info_finally_branch;
     }
 
-    gc_freeze(inter, new, false);
     setWithResult(yield_run, with_list, st, result, value, _enter_, _exit_, with_belong, result_from, CFUNC_CORE(new));
     if (set_result)
         setResult(result, inter);

+ 0 - 7
vmcore/src/runcall.c

@@ -24,10 +24,8 @@ ResultType setClass(FUNC) {
         inter->data.default_pt_type = object_free_;
         tmp->value->object.var->next = var_list;
 
-        gc_freeze(inter, var_backup, true);
         // 运行类定义的时候需要调整belong
         functionSafeInterStatement(CFUNC(st->u.set_class.st, tmp->value->object.var, result, tmp));
-        gc_freeze(inter, var_backup, false);
 
         tmp->value->object.var->next = var_backup;
         inter->data.default_pt_type = pt_type_bak;
@@ -232,7 +230,6 @@ static ResultType callCFunction(LinkValue *func_value, Argument *arg, long int l
 
     of = func_value->value->data.function.of;
     function_var = pushVarList(func_value->value->object.out_var != NULL ? func_value->value->object.out_var : var_list, inter);
-    gc_freeze(inter, var_list, true);
 
     freeResult(result);
     of(CO_FUNC(arg, function_var, result, func_value->belong));  // belong设置为func的belong, 方便权限的认定
@@ -241,7 +238,6 @@ static ResultType callCFunction(LinkValue *func_value, Argument *arg, long int l
     else if (result->type != R_opt && result->type != R_error)
         setResult(result, inter);
 
-    gc_freeze(inter, var_list, false);
     popVarList(function_var);
     freeFunctionArgument(arg, bak);
 
@@ -465,7 +461,6 @@ static void updateFunctionYield(Statement *func_st, Statement *node){
 
 static void newFunctionYield(Statement *func_st, Statement *node, VarList *new_var, Inter *inter){
     new_var->next = NULL;
-    gc_freeze(inter, new_var, true);
     func_st->info.var_list = new_var;
     func_st->info.node = node->type == yield_code ? node->next : node;
     func_st->info.have_info = true;
@@ -516,7 +511,6 @@ static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int
     if (yield_run)
         st_func = st_func->info.node;
 
-    gc_freeze(inter, var_list, true);
     setFunctionArgument(&arg, &bak, func_value, line, file, pt_sep, CNEXT_NT);
     if (!CHECK_RESULT(result))
         goto return_;
@@ -534,7 +528,6 @@ static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int
     functionSafeInterStatement(CFUNC(st_func, var_func, result, func_value->belong));  // belong设置为函数的belong,方便权限校对
 
     return_:
-    gc_freeze(inter, var_list, false);
     setFunctionResult(func_value, yield_run, result, CFUNC_CORE(var_func));
     gc_freeTmpLink(&func_value->gc_status);
     return result->type;

+ 0 - 4
vmcore/src/runfile.c

@@ -235,7 +235,6 @@ ResultType importFile(FUNC) {
     char md5_str[MD5_STRING];
 
     setResultCore(result);
-    gc_freeze(inter, var_list, true);
 
     importFileCore(&path, &split_path, &status, CFUNC(file, var_list, result, belong));
     if (!CHECK_RESULT(result))
@@ -260,7 +259,6 @@ ResultType importFile(FUNC) {
     return_:
     memFree(split_path);
     memFree(path);
-    gc_freeze(inter, var_list, false);
     return result->type;
 }
 
@@ -293,7 +291,6 @@ ResultType fromImportFile(FUNC) {
     Parameter *as = st->u.from_import_file.as != NULL ? st->u.from_import_file.as : st->u.from_import_file.pt;
 
     setResultCore(result);
-    gc_freeze(inter, var_list, true);
     importFileCore(&path, &split_path, &status, CFUNC(file, var_list, result, belong));
     if (!CHECK_RESULT(result))
         goto return_;
@@ -332,6 +329,5 @@ ResultType fromImportFile(FUNC) {
     return_:
     memFree(path);
     memFree(split_path);
-    gc_freeze(inter, var_list, false);
     return result->type;
 }

+ 0 - 7
vmcore/src/runoperation.c

@@ -81,7 +81,6 @@ static void updateBlockYield(Statement *block_st, Statement *node){
 
 static void newBlockYield(Statement *block_st, Statement *node, VarList *new_var, Inter *inter){
     new_var->next = NULL;
-    gc_freeze(inter, new_var, true);
     block_st->info.var_list = new_var;
     block_st->info.node = node->type == yield_code ? node->next : node;
     block_st->info.have_info = true;
@@ -190,14 +189,12 @@ ResultType pointOperation(FUNC) {
         setResultError(E_TypeException, OBJ_NOTSUPPORT(->/.), st->line, st->code_file, true, CNEXT_NT);
         goto return_;
     }
-    gc_freeze(inter, var_list, true);
     operationSafeInterStatement(CFUNC(st->u.operation.right, object, result, left));  // 点运算运算时需要调整belong为点的左值
     pri_auto = result->value->belong == NULL || result->value->belong->value == belong->value || checkAttribution(belong->value, result->value->belong->value);
     if (!CHECK_RESULT(result) || !checkAut(left->aut, result->value->aut, st->line, st->code_file, NULL, pri_auto, CNEXT_NT))
         PASS;
     else if (result->value->belong == NULL || result->value->belong->value == left->value || checkAttribution(left->value, result->value->belong->value))  // 检查result所属于的对象是否位左值的父亲
         result->value->belong = left;
-    gc_freeze(inter, var_list, false);
 
     return_:
     gc_freeTmpLink(&left->gc_status);
@@ -273,12 +270,10 @@ ResultType pointDel(Statement *name, FUNC_NT) {
         goto return_;
     }
 
-    gc_freeze(inter, var_list, true);
     if (right->type == T_OPERATION && (right->u.operation.OperationType == OPT_POINT || right->u.operation.OperationType == OPT_OUTPOINT))
         pointDel(name->u.operation.right, CFUNC_NT(object, result, belong));
     else
         delCore(name->u.operation.right, true, CFUNC_NT(object, result, belong));
-    gc_freeze(inter, var_list, false);
 
     return_:
     gc_freeTmpLink(&left->gc_status);
@@ -491,12 +486,10 @@ ResultType pointAss(Statement *name, LinkValue *value, FUNC_NT) {
         goto return_;
     }
 
-    gc_freeze(inter, var_list, true);
     if (right->type == T_OPERATION && (right->u.operation.OperationType == OPT_POINT || right->u.operation.OperationType == OPT_OUTPOINT))
         pointAss(name->u.operation.right, value, CFUNC_NT(object, result, belong));
     else
         assCore(name->u.operation.right, value, true, false, CFUNC_NT(object, result, belong));
-    gc_freeze(inter, var_list, false);
 
     return_:
     gc_freeTmpLink(&left->gc_status);

+ 10 - 17
vmcore/src/var.c

@@ -78,13 +78,16 @@ void freeHashTable(HashTable **value) {
     return_: return;
 }
 
-VarList *makeVarList(Inter *inter, bool make_hash) {
+VarList *makeVarList(Inter *inter, bool make_hash, HashTable *hs) {
     VarList *tmp = calloc(1, sizeof(VarList));
     tmp->next = NULL;
     if (make_hash)
         tmp->hashtable = makeHashTable(inter);
-    else
-        tmp->hashtable = NULL;
+    else {
+        assert(hs != NULL);
+        tmp->hashtable = hs;
+    }
+    gc_addTmpLink(&tmp->hashtable->gc_status);
     tmp->default_var = NULL;
     return tmp;
 }
@@ -95,6 +98,8 @@ VarList *freeVarList(VarList *vl) {
     next_var = vl->next;
     for (PASS; vl->default_var != NULL; vl->default_var = freeDefaultVar(vl->default_var))
         PASS;
+    if (vl->hashtable != NULL)
+        gc_freeTmpLink(&vl->hashtable->gc_status);
     memFree(vl);
     return_:
     return next_var;
@@ -234,23 +239,11 @@ void addFromVarList(wchar_t *name, LinkValue *name_, vint times, LinkValue *valu
 }
 
 VarList *pushVarList(VarList *base, Inter *inter){
-    VarList *new = makeVarList(inter, true);
+    VarList *new = makeVarList(inter, true, NULL);
     new->next = base;
     return new;
 }
 
-VarList *popVarList(VarList *base) {
-    if (base->next == NULL)
-        return base;
-    return freeVarList(base);
-}
-
-VarList *copyVarListCore(VarList *base, Inter *inter){
-    VarList *tmp = makeVarList(inter, false);
-    tmp->hashtable = base->hashtable;
-    return tmp;
-}
-
 VarList *copyVarList(VarList *base, bool n_new, Inter *inter){
     VarList *new = NULL;
     VarList **tmp = &new;
@@ -270,7 +263,7 @@ VarList *connectVarListBack(VarList *base, VarList *back){
 }
 
 VarList *makeObjectVarList(Inherit *value, Inter *inter, VarList *base) {
-    VarList *tmp = base == NULL ? makeVarList(inter, true) : base;
+    VarList *tmp = base == NULL ? makeVarList(inter, true, NULL) : base;
     for (PASS; value != NULL; value = value->next) {
         VarList *new = copyVarList(value->value->value->object.var, false, inter);
         tmp = connectVarListBack(tmp, new);