Selaa lähdekoodia

refactor: 修改了makeValue类函数和opt的执行策略

SongZihuan 4 vuotta sitten
vanhempi
sitoutus
0ac3ae3216

+ 7 - 8
CMakeLists.txt

@@ -6,8 +6,13 @@ OPTION(GC "GC" ON)
 OPTION(PG "PG" OFF)
 OPTION(SET_DEBUG "SET_DEBUG" ON)
 
-SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
+IF (SET_DEBUG)
+    ADD_DEFINITIONS(-DDEBUG=1)
+ELSE()
+    ADD_DEFINITIONS(-DDEBUG=0)
+    SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
+    SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
+ENDIF()
 
 IF (NOT PG)
     SET(LIBRARY_OUTPUT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib-${CMAKE_BUILD_TYPE})
@@ -24,12 +29,6 @@ SET(HELLOVM_INCLUDE_DICT
         ${CMAKE_CURRENT_SOURCE_DIR}/vmcore/include
         )
 
-IF (SET_DEBUG)
-    ADD_DEFINITIONS(-DDEBUG=1)
-ELSE()
-    ADD_DEFINITIONS(-DDEBUG=0)
-ENDIF()
-
 IF (GC)
     ADD_DEFINITIONS(-DSTART_GC=1)
 ELSE()

+ 6 - 0
vmcore/include/__macro.h

@@ -26,6 +26,12 @@
 #define R_FUNC struct LinkValue *belong, FUNC_CORE
 #define CR_FUNC(belong, var_list) belong, CFUNC_CORE(var_list)
 
+#define FUNC_VOBJ struct LinkValue *belong, struct Result *result, struct Inter *inter, struct VarList *var_list, struct Value *left, struct Value *right
+#define CFUNC_VOBJ(var_list, result, belong, left, right) belong, result, inter, var_list, left, right
+
+#define FUNC_VOBJR struct LinkValue *belong, struct Result *result, struct Inter *inter, struct VarList *var_list, struct Value *left
+#define CFUNC_VOBJR(var_list, result, belong, left) belong, result, inter, var_list, left
+
 #define LINEFILE __LINE__, __FILE__
 
 #ifdef __linux__

+ 6 - 0
vmcore/include/inter.h

@@ -125,6 +125,12 @@ struct Inter{
         } assert_run;
         int run_gc;  // gc的启动计数
         bool start_gc;  // 是否启动gc
+        bool free_mode;  // 自由模式
+        enum OptMode {
+            om_free,
+            om_normal,
+            om_simple,
+        } opt_mode;
     } data;
 };
 

+ 36 - 0
vmcore/include/ofunc.h

@@ -29,9 +29,45 @@ struct NameFunc{
     wchar_t *name;
     OfficialFunction of;
     enum FunctionPtType type;
+    enum NameFuncVar {
+        nfv_inline,
+        nfv_notpush,
+        nfv_default,
+    } var;
 };
 typedef struct NameFunc NameFunc;
 
 void registeredBaseFunction(struct LinkValue *father, Inter *inter);
 void registeredFunctionName(Inter *inter, LinkValue *belong);
+
+// 普通模式函数
+LinkValue *intCore(LinkValue *belong, LinkValue *class, Inter *inter);
+LinkValue *strCore(LinkValue *belong, LinkValue *class, Inter *inter);
+LinkValue *boolCore(LinkValue *belong, LinkValue *class, Inter *inter);
+LinkValue *douCore(LinkValue *belong, LinkValue *class, Inter *inter);
+LinkValue *passCore(LinkValue *belong, LinkValue *class, Inter *inter);
+
+#define SET_DECLARATION(NAME) void vobject_##NAME##_base(FUNC_VOBJ)
+SET_DECLARATION(add);
+SET_DECLARATION(sub);
+SET_DECLARATION(mul);
+SET_DECLARATION(div);
+SET_DECLARATION(intdiv);
+SET_DECLARATION(mod);
+SET_DECLARATION(pow);
+SET_DECLARATION(eq);
+SET_DECLARATION(noteq);
+SET_DECLARATION(moreeq);
+SET_DECLARATION(lesseq);
+SET_DECLARATION(more);
+SET_DECLARATION(less);
+SET_DECLARATION(band);
+SET_DECLARATION(bor);
+SET_DECLARATION(bxor);
+SET_DECLARATION(bl);
+SET_DECLARATION(br);
+void vobject_bnot_base(FUNC_VOBJR);
+void vobject_negate_base(FUNC_VOBJR);
+#undef SET_DECLARATION
+
 #endif //VIRTUALMATH_OFUNC_H

+ 3 - 0
vmcore/include/statement.h

@@ -251,6 +251,9 @@ struct Statement{
             struct{
                 LinkValue *iter;
             } for_;
+            struct {
+                bool push;
+            } func;
         } branch;
     } info;
     fline line;

+ 10 - 4
vmcore/include/value.h

@@ -16,7 +16,12 @@
 
 #define GET_RESULT(val, res) do {(val) = (res)->value; (res)->value=NULL; freeResult(res);} while(0)
 #define GET_RESULTONLY(val, res) do {(val) = (res)->value; (res)->value=NULL;} while(0)
-#define copyLinkValue(val, inter) makeLinkValue((val)->value, (val)->belong, (val)->aut, (inter))
+
+#define COPY_LINKVALUE(val, inter) makeLinkValue((val)->value, (val)->belong, (val)->aut, (inter))
+
+#define NORMAL_BUILTIN(val) ((val)->type != V_obj && (val)->type != V_class)
+#define SIMPLE_BUILTIN(val, inter) (((val)->object.inherit != NULL && (val)->object.inherit->next != NULL) && (val)->object.inherit->next->value->value == (inter)->data.base_obj[B_VOBJECT]->value)
+#define IS_BUILTIN_VALUE(val, inter) (((inter)->data.opt_mode == om_normal && NORMAL_BUILTIN(val)) || (inter->data.opt_mode == om_simple && NORMAL_BUILTIN(val) && SIMPLE_BUILTIN(val, inter)))
 
 typedef struct Argument Argument;
 typedef struct Inter Inter;
@@ -95,6 +100,7 @@ struct Function{
         } pt_type;
         LinkValue *cls;
         bool run;  // 是否为即时调用
+        bool push;  // 是否需要push var
     } function_data;
 };
 
@@ -230,7 +236,7 @@ enum BaseErrorType{
     E_QuitException,
 };
 
-Value *makeObject(Inter *inter, VarList *object, VarList *out_var, Inherit *inherit);
+Value *makeObject(Inter *inter, VarList *object, VarList *out_var, bool set_out_var, Inherit *inherit);
 void freeValue(Value **Value);
 LinkValue *makeLinkValue(Value *value, LinkValue *belong, enum ValueAuthority aut, Inter *inter);
 void freeLinkValue(LinkValue **value);
@@ -242,8 +248,8 @@ Value *makeDouValue(vdou num, fline line, char *file, FUNC_NT);
 Value *makePointerValue(void *p, fline line, char *file, FUNC_NT);
 Value *makeStringValue(wchar_t *str, fline line, char *file, FUNC_NT);
 Value *makeVMFunctionValue(struct Statement *st, struct Parameter *pt, FUNC_NT);
-Value *makeCFunctionValue(OfficialFunction of, fline line, char *file, FUNC_NT);
-LinkValue *makeCFunctionFromOf(OfficialFunction of, LinkValue *func, OfficialFunction function_new, OfficialFunction function_init, LinkValue *belong, VarList *var_list, Inter *inter);
+Value *makeCFunctionValue(OfficialFunction of, fline line, char *file, bool set_var, bool push, FUNC_NT);
+LinkValue *makeCFunctionFromOf(OfficialFunction of, LinkValue *func, OfficialFunction function_new, LinkValue *belong, VarList *var_list, Inter *inter);
 Value *makeFFunctionValue(void (*ffunc)(), fline line, char *file, FUNC_NT);
 Value *makeClassValue(VarList *var_list, Inter *inter, Inherit *father);
 Value *makeListValue(Argument *arg, fline line, char *file, enum ListType type, FUNC_NT);

+ 1 - 1
vmcore/include/var.h

@@ -3,7 +3,7 @@
 
 #define MAX_SIZE (8)
 #define copyVarListCore(base, inter) makeVarList((inter), false, (base)->hashtable)
-#define popVarList(base) (((base)->next == NULL) ? (base) : freeVarList(base))
+#define popVarList(base) (((base) == NULL) ? (base) : freeVarList(base))
 
 struct Var{
     GCStatus gc_status;

+ 1 - 1
vmcore/ofunc/include/__ofunc.h

@@ -5,7 +5,7 @@
 #include "__run.h"
 
 void newObjectSettingPresetting(LinkValue *func, LinkValue *name, Inter *inter);
-LinkValue *registeredFunctionCore(OfficialFunction of, wchar_t *name, FUNC_NT);
+LinkValue *registeredFunctionCore(OfficialFunction of, wchar_t *name, enum NameFuncVar nfv, FUNC_NT);
 
 bool iterNameFunc(NameFunc *list, FUNC_NT);
 bool iterClassFunc(NameFunc *list, FUNC_NT);

+ 1 - 2
vmcore/ofunc/include/function.h

@@ -1,7 +1,6 @@
 #ifndef VIRTUALMATH_FUNCTION_H
 #define VIRTUALMATH_FUNCTION_H
 void registeredFunction(R_FUNC);
-void functionPresetting(LinkValue *func, LinkValue **func_new, LinkValue **func_init, Inter *inter);
-void functionPresettingLast(LinkValue *func, LinkValue *func_new, LinkValue *func_init, Inter *inter);
+void functionPresetting(LinkValue *func, Inter *inter);
 void makeBaseFunction(Inter *inter);
 #endif //VIRTUALMATH_FUNCTION_H

+ 14 - 4
vmcore/ofunc/src/__ofunc.c

@@ -1,8 +1,18 @@
 #include "__ofunc.h"
 
-LinkValue *registeredFunctionCore(OfficialFunction of, wchar_t *name, FUNC_NT) {
+LinkValue *registeredFunctionCore(OfficialFunction of, wchar_t *name, enum NameFuncVar nfv, FUNC_NT) {
     LinkValue *value = NULL;
-    makeCFunctionValue(of, LINEFILE, CNEXT_NT);
+    switch (nfv) {
+        case nfv_notpush:
+            makeCFunctionValue(of, LINEFILE, true, false, CNEXT_NT);
+            break;
+        case nfv_inline:
+            makeCFunctionValue(of, LINEFILE, false, true, CNEXT_NT);
+            break;
+        default:
+            makeCFunctionValue(of, LINEFILE, true, true, CNEXT_NT);
+            break;
+    }
     GET_RESULT(value, result);
     addStrVar(name, false, true, value, LINEFILE, false, CNEXT_NT);
     gc_freeTmpLink(&value->gc_status);
@@ -12,7 +22,7 @@ LinkValue *registeredFunctionCore(OfficialFunction of, wchar_t *name, FUNC_NT) {
 bool iterNameFunc(NameFunc *list, FUNC_NT){
     setResultCore(result);
     for (PASS; list->of != NULL; list++) {
-        LinkValue *value = registeredFunctionCore(list->of, list->name, CNEXT_NT);
+        LinkValue *value = registeredFunctionCore(list->of, list->name, list->var, CNEXT_NT);
         if (!CHECK_RESULT(result))
             return false;
         value->value->data.function.function_data.pt_type = list->type;
@@ -32,7 +42,7 @@ bool iterClassFunc(NameFunc *list, FUNC_NT){
     inter->data.default_pt_type = object_free_;
 
     for (PASS; list->of != NULL; list++) {
-        LinkValue *value = registeredFunctionCore(list->of, list->name, CFUNC_NT(object_var, result, belong));
+        LinkValue *value = registeredFunctionCore(list->of, list->name, list->var, CFUNC_NT(object_var, result, belong));
         if (!CHECK_RESULT(result)) {
             return_ = false;
             break;

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

@@ -1,5 +1,13 @@
 #include "__ofunc.h"
 
+LinkValue *boolCore(LinkValue *belong, LinkValue *class, Inter *inter) {
+    LinkValue *value;
+    value = make_new(inter, belong, class);
+    value->value->type = V_bool;
+    value->value->data.bool_.bool_ = false;
+    return value;
+}
+
 ResultType bool_new(O_FUNC){
     LinkValue *value = NULL;
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
@@ -45,8 +53,8 @@ ResultType bool_init(O_FUNC){
 
 void registeredBool(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_BOOL];
-    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], bool_new, class_free_},
-                      {inter->data.mag_func[M_INIT], bool_init, object_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], bool_new, class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], bool_init, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"bool", object, belong, inter);

+ 6 - 6
vmcore/ofunc/src/dict.c

@@ -132,7 +132,7 @@ ResultType dict_keys(O_FUNC){
     for (int index=0; index < MAX_SIZE; index++){
         Var *tmp = ap[0].value->value->data.dict.dict->hashtable[index];
         for (PASS; tmp != NULL; tmp = tmp->next)
-            list = connectValueArgument(copyLinkValue(tmp->name_, inter), list);
+            list = connectValueArgument(COPY_LINKVALUE(tmp->name_, inter), list);
     }
     makeListValue(list, LINEFILE, L_list, CNEXT_NT);
     freeArgument(list, true);
@@ -247,11 +247,11 @@ ResultType dict_str(O_FUNC){
 void registeredDict(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_DICT];
     NameFunc tmp[] = {{L"keys", dict_keys, object_free_},
-                      {inter->data.mag_func[M_NEW], dict_new, class_free_},
-                      {inter->data.mag_func[M_DOWN], dict_down, object_free_},
-                      {inter->data.mag_func[M_ITER], dict_iter, object_free_},
-                      {inter->data.mag_func[M_REPO], dict_repo, object_free_},
-                      {inter->data.mag_func[M_STR], dict_str, object_free_},
+                      {inter->data.mag_func[M_NEW], dict_new, class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_DOWN], dict_down, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_ITER], dict_iter, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_REPO], dict_repo, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_STR], dict_str, object_free_, .var=nfv_notpush},
                       {inter->data.mag_func[M_DOWN_ASSIGMENT], dict_down_assignment, object_free_},
                       {inter->data.mag_func[M_DOWN_DEL], dict_down_del, object_free_},
                       {NULL, NULL}};

+ 3 - 3
vmcore/ofunc/src/dictiter.c

@@ -124,9 +124,9 @@ ResultType dictiter_down(O_FUNC){
 
 void registeredDictIter(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_DICTITER];
-    NameFunc tmp[] = {{inter->data.mag_func[M_INIT], dictiter_init, object_free_},
-                      {inter->data.mag_func[M_NEXT], dictiter_next, object_free_},
-                      {inter->data.mag_func[M_DOWN], dictiter_down, object_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_INIT], dictiter_init, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_NEXT], dictiter_next, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_DOWN], dictiter_down, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"dictiter", object, belong, inter);

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

@@ -1,5 +1,13 @@
 #include "__ofunc.h"
 
+LinkValue *douCore(LinkValue *belong, LinkValue *class, Inter *inter) {
+    LinkValue *value;
+    value = make_new(inter, belong, class);
+    value->value->type = V_dou;
+    value->value->data.dou.num = 0.;
+    return value;
+}
+
 ResultType dou_new(O_FUNC){
     LinkValue *value = NULL;
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
@@ -65,8 +73,8 @@ ResultType dou_init(O_FUNC){
 
 void registeredDou(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_DOU];
-    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], dou_new, class_free_},
-                      {inter->data.mag_func[M_INIT], dou_init, object_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], dou_new, class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], dou_init, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"dou", object, belong, inter);

+ 1 - 1
vmcore/ofunc/src/error_.c

@@ -45,7 +45,7 @@ void registeredExcIter(R_FUNC){
                    {NULL, NULL}};
     {
         LinkValue *object = inter->data.base_exc[E_BaseException];
-        NameFunc tmp[] = {{L"__init__", base_exception_init, object_free_},
+        NameFunc tmp[] = {{L"__init__", base_exception_init, object_free_, .var=nfv_notpush},
                           {NULL, NULL}};
         gc_addTmpLink(&object->gc_status);
         addBaseClassVar(L"BaseException", object, belong, inter);

+ 14 - 14
vmcore/ofunc/src/file_.c

@@ -354,20 +354,20 @@ ResultType file_enter(O_FUNC){
 
 void registeredFile(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_FILE];
-    NameFunc tmp[] = {{L"read", file_read, object_free_},
-                      {L"write", file_write, object_free_},
-                      {L"close", file_close, object_free_},
-                      {L"get_seek", file_get_seek, object_free_},
-                      {L"seek", file_seek, object_free_},
-                      {L"readline", file_readline, object_free_},
-                      {L"end", file_isend, object_free_},
-                      {L"err", file_iserr, object_free_},
-                      {L"clean", file_clean_err, object_free_},
-                      {inter->data.mag_func[M_ENTER], file_enter, object_free_},
-                      {inter->data.mag_func[M_DEL], file_close, object_free_},
-                      {inter->data.mag_func[M_EXIT], file_close, object_free_},
-                      {inter->data.mag_func[M_NEW], file_new, class_free_},
-                      {inter->data.mag_func[M_INIT], file_init, object_free_},
+    NameFunc tmp[] = {{L"read", file_read, object_free_, .var=nfv_notpush},
+                      {L"write", file_write, object_free_, .var=nfv_notpush},
+                      {L"close", file_close, object_free_, .var=nfv_notpush},
+                      {L"get_seek", file_get_seek, object_free_, .var=nfv_notpush},
+                      {L"seek", file_seek, object_free_, .var=nfv_notpush},
+                      {L"readline", file_readline, object_free_, .var=nfv_notpush},
+                      {L"end", file_isend, object_free_, .var=nfv_notpush},
+                      {L"err", file_iserr, object_free_, .var=nfv_notpush},
+                      {L"clean", file_clean_err, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_ENTER], file_enter, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_DEL], file_close, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_EXIT], file_close, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_NEW], file_new, class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], file_init, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"file", object, belong, inter);

+ 9 - 13
vmcore/ofunc/src/function.c

@@ -4,6 +4,7 @@ static void setFunctionData(Value *value, LinkValue *cls, Inter *inter) {
     value->data.function.function_data.pt_type = inter->data.default_pt_type;
     value->data.function.function_data.cls = cls;
     value->data.function.function_data.run = false;
+    value->data.function.function_data.push = true;
 }
 
 ResultType function_new(O_FUNC){
@@ -18,10 +19,9 @@ ResultType function_new(O_FUNC){
         return R_error;
     }
 
-    {
+    {  // 不使用make_new, 需要设定makeObject的set_out_var
         Inherit *object_father = getInheritFromValueCore(inter->data.base_obj[B_FUNCTION]);
-        VarList *new_var = copyVarList(var_list, false, inter);
-        Value *new_object = makeObject(inter, NULL, new_var, object_father);
+        Value *new_object = makeObject(inter, NULL, NULL, false, object_father);  // 不加入out_var
         value = makeLinkValue(new_object, belong, auto_aut, inter);
         gc_freeTmpLink(&new_object->gc_status);
     }
@@ -96,7 +96,8 @@ ResultType function_set(O_FUNC){  // 针对FFI设置vaargs
 
 void registeredFunction(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_FUNCTION];
-    NameFunc tmp[] = {{L"set", function_set, object_free_},
+    NameFunc tmp[] = {{L"set", function_set, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], function_init, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"func", object, belong, inter);
@@ -110,20 +111,15 @@ void makeBaseFunction(Inter *inter){
     inter->data.base_obj[B_FUNCTION] = function;
 }
 
-void functionPresetting(LinkValue *func, LinkValue **func_new, LinkValue **func_init, Inter *inter) {
-    *func_new = makeCFunctionFromOf(function_new, func, function_new, function_init, func, inter->var_list, inter);
-    *func_init = makeCFunctionFromOf(function_init, func, function_new, function_init, func, inter->var_list, inter);
-    (*func_new)->value->data.function.function_data.pt_type = class_free_;
-    (*func_init)->value->data.function.function_data.pt_type = object_free_;
-}
-
-void functionPresettingLast(LinkValue *func, LinkValue *func_new, LinkValue *func_init, Inter *inter) {
+void functionPresetting(LinkValue *func, Inter *inter) {  // 提前注册func_new
     Result result;
     VarList *object_var = func->value->object.var;
+    LinkValue *func_new;
     setResultCore(&result);
 
+    func_new = makeCFunctionFromOf(function_new, func, function_new, func, NULL, inter);  // var_list为NULL, 即声明为内联函数 (若不声明为内联函数则改为inter.var_list即可)
+    func_new->value->data.function.function_data.pt_type = class_free_;
     addStrVar(inter->data.mag_func[M_NEW], false, true, func_new, LINEFILE, false, CFUNC_NT(object_var, &result, func));
     freeResult(&result);
-    addStrVar(inter->data.mag_func[M_INIT], false, true, func_init, LINEFILE, false, CFUNC_NT(object_var, &result, func));
     freeResult(&result);
 }

+ 11 - 3
vmcore/ofunc/src/int.c

@@ -1,5 +1,13 @@
 #include "__ofunc.h"
 
+LinkValue *intCore(LinkValue *belong, LinkValue *class, Inter *inter) {
+    LinkValue *value;
+    value = make_new(inter, belong, class);
+    value->value->type = V_int;
+    value->value->data.int_.num = 0;
+    return value;
+}
+
 ResultType int_new(O_FUNC){
     LinkValue *value = NULL;
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
@@ -12,7 +20,7 @@ ResultType int_new(O_FUNC){
     }
 
     setResultCore(result);
-    value = make_new(inter, belong, ap[0].value);
+    value = make_new(inter, belong, ap[0].value);  // 需要保持和``intCore``效果相同
     value->value->type = V_int;
     value->value->data.int_.num = 0;
     run_init(value, arg, LINEFILE, CNEXT_NT);
@@ -65,8 +73,8 @@ ResultType int_init(O_FUNC){
 
 void registeredInt(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_INT_];
-    NameFunc tmp[] = {{inter->data.mag_func[M_NEW],  int_new,  class_free_},
-                      {inter->data.mag_func[M_INIT], int_init, object_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_NEW],  int_new,  class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], int_init, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"int", object, belong, inter);

+ 2 - 2
vmcore/ofunc/src/io.c

@@ -53,8 +53,8 @@ ResultType vm_input(O_FUNC){
 }
 
 void registeredIOFunction(R_FUNC){
-    NameFunc tmp[] = {{L"print", vm_print, free_},
-                      {L"input", vm_input, free_},
+    NameFunc tmp[] = {{L"print", vm_print, free_, .var=nfv_notpush},
+                      {L"input", vm_input, free_, .var=nfv_notpush},
                       {NULL, NULL}};
     iterBaseNameFunc(tmp, belong, CFUNC_CORE(var_list));
 }

+ 6 - 6
vmcore/ofunc/src/lib_.c

@@ -172,12 +172,12 @@ ResultType lib_attr(O_FUNC){
 
 void registeredLib(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_LIB];
-    NameFunc tmp[] = {{L"close", lib_close, object_free_},
-                      {L"add", lib_add, object_free_},
-                      {inter->data.mag_func[M_NEW], lib_new, class_free_},
-                      {inter->data.mag_func[M_INIT], lib_init, object_free_},
-                      {inter->data.mag_func[M_DEL], lib_close, object_free_},
-                      {inter->data.mag_func[M_ATTR], lib_attr, object_free_},
+    NameFunc tmp[] = {{L"close", lib_close, object_free_, .var=nfv_notpush},
+                      {L"add", lib_add, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_NEW], lib_new, class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], lib_init, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_DEL], lib_close, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_ATTR], lib_attr, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"clib", object, belong, inter);

+ 4 - 4
vmcore/ofunc/src/list.c

@@ -314,7 +314,7 @@ ResultType list_down(O_FUNC){
     if (!checkIndex(&index, &size, CNEXT_NT))
         return result->type;
     element = ap[0].value->value->data.list.list[index];
-    setResultOperationBase(result, copyLinkValue(element, inter));
+    setResultOperationBase(result, COPY_LINKVALUE(element, inter));
     return result->type;
 }
 
@@ -436,9 +436,9 @@ void registeredList(R_FUNC){
 
     {
         LinkValue *object = inter->data.base_obj[B_LIST];
-        NameFunc tmp[] = {{inter->data.mag_func[M_NEW], list_new, class_free_},
-                          {inter->data.mag_func[M_DOWN_ASSIGMENT], list_down_assignment, object_free_},
-                          {inter->data.mag_func[M_SLICE_ASSIGMENT], list_slice_assignment, object_free_},
+        NameFunc tmp[] = {{inter->data.mag_func[M_NEW], list_new, class_free_, .var=nfv_notpush},
+                          {inter->data.mag_func[M_DOWN_ASSIGMENT], list_down_assignment, object_free_, .var=nfv_notpush},
+                          {inter->data.mag_func[M_SLICE_ASSIGMENT], list_slice_assignment, object_free_, .var=nfv_notpush},
                           {NULL, NULL}};
         gc_addTmpLink(&object->gc_status);
         addBaseClassVar(L"list", object, belong, inter);

+ 2 - 2
vmcore/ofunc/src/listiter.c

@@ -90,8 +90,8 @@ ResultType listiter_next(O_FUNC){
 
 void registeredListIter(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_LISTITER];
-    NameFunc tmp[] = {{inter->data.mag_func[M_INIT], listiter_init, object_free_},
-                      {inter->data.mag_func[M_NEXT], listiter_next, object_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_INIT], listiter_init, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_NEXT], listiter_next, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"listiter", object, belong, inter);

+ 4 - 4
vmcore/ofunc/src/object.c

@@ -73,9 +73,9 @@ ResultType object_str(O_FUNC){
 
 void registeredObject(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_OBJECT];
-    NameFunc tmp[] = {{inter->data.mag_func[M_NEW],  object_new,  class_free_},
-                      {inter->data.mag_func[M_REPO], object_repo, all_free_},
-                      {inter->data.mag_func[M_STR],  object_str,  all_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_NEW],  object_new,  class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_REPO], object_repo, all_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_STR],  object_str,  all_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"object", object, belong, inter);
@@ -88,7 +88,7 @@ void makeBaseObject(Inter *inter, LinkValue *belong){
     Value *object = makeClassValue(inter->var_list, inter, NULL);
 
     {
-        Value *global_belong = makeObject(inter, copyVarList(inter->var_list, false, inter), NULL, NULL);
+        Value *global_belong = makeObject(inter, copyVarList(inter->var_list, false, inter), NULL, true, NULL);
         g_belong = makeLinkValue(global_belong, belong, auto_aut, inter);
         gc_freeTmpLink(&global_belong->gc_status);
         inter->base_belong = g_belong;

+ 8 - 1
vmcore/ofunc/src/pass.c

@@ -1,5 +1,12 @@
 #include "__ofunc.h"
 
+LinkValue *passCore(LinkValue *belong, LinkValue *class, Inter *inter) {
+    LinkValue *value;
+    value = make_new(inter, belong, class);
+    value->value->type = V_ell;
+    return value;
+}
+
 ResultType pass_new(O_FUNC){
     LinkValue *value = NULL;
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
@@ -20,7 +27,7 @@ ResultType pass_new(O_FUNC){
 
 void registeredEllipisis(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_PASS];
-    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], pass_new, class_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], pass_new, class_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"ellipsis", object, belong, inter);

+ 2 - 2
vmcore/ofunc/src/pointer.c

@@ -53,8 +53,8 @@ ResultType pointer_init(O_FUNC){
 
 void registeredPointer(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_POINTER];
-    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], pointer_new, class_free_},
-                      {inter->data.mag_func[M_INIT], pointer_init, object_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_NEW], pointer_new, class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], pointer_init, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"pointer", object, belong, inter);

+ 19 - 8
vmcore/ofunc/src/str.c

@@ -1,5 +1,13 @@
 #include "__ofunc.h"
 
+LinkValue *strCore(LinkValue *belong, LinkValue *class, Inter *inter) {
+    LinkValue *value;
+    value = make_new(inter, belong, class);
+    value->value->type = V_str;
+    value->value->data.str.str = NULL;  // 设置为NULL, 因此strCore不能单独使用, strCore()后需要显式设定str的内容
+    return value;
+}
+
 ResultType str_new(O_FUNC){
     LinkValue *value = NULL;
     ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
@@ -13,7 +21,7 @@ ResultType str_new(O_FUNC){
     }
     freeResult(result);
 
-    value = make_new(inter, belong, ap[0].value);
+    value = make_new(inter, belong, ap[0].value);  // 保持与strCore的行为相同
     value->value->type = V_str;
     value->value->data.str.str = memWidecpy(L"");
     run_init(value, arg, LINEFILE, CNEXT_NT);
@@ -184,10 +192,13 @@ ResultType str_iter(O_FUNC){
 
 void registeredStr(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_STR];
-    NameFunc tmp[] = {{L"to_list", str_to_list, object_free_},
-                      {inter->data.mag_func[M_ITER], str_iter, object_free_},
-                      {inter->data.mag_func[M_DOWN], str_down, object_free_},
-                      {inter->data.mag_func[M_SLICE], str_slice, object_free_},
+    NameFunc tmp[] = {{L"to_list", str_to_list, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_NEW], str_new, class_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INIT], str_init, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_SLICE], str_slice, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_ITER], str_iter, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_DOWN], str_down, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_SLICE], str_slice, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     iterBaseClassFunc(tmp, object, CFUNC_CORE(inter->var_list));
@@ -224,7 +235,7 @@ LinkValue *makeStrFromOf(LinkValue *str, LinkValue *new, LinkValue *init, wchar_
     return return_;
 }
 
-LinkValue *makeFunctionFromValue(LinkValue *func, LinkValue *new, LinkValue *init, OfficialFunction of, LinkValue *belong, VarList *var_list, Inter *inter) {
+static LinkValue *makeFunctionFromValue(LinkValue *func, LinkValue *new, LinkValue *init, OfficialFunction of, LinkValue *belong, VarList *var_list, Inter *inter) {
     LinkValue *new_func;
     new_func = callClassOf(func, inter, new, init);
     new_func->value->data.function.type = c_func;
@@ -248,9 +259,9 @@ void strFunctionPresetting(LinkValue *func, LinkValue *func_new, LinkValue *func
     LinkValue *init_name = NULL;
     wchar_t *init_name_ = setStrVarName(inter->data.mag_func[M_INIT], false, inter);
 
-    new_func = makeFunctionFromValue(func, func_new, func_init, str_new, obj, obj->value->object.var, inter);
+    new_func = makeFunctionFromValue(func, func_new, func_init, str_new, obj, NULL, inter);  // 声明为内联函数
+    init_func = makeFunctionFromValue(func, func_new, func_init, str_init, obj, NULL, inter);
     new_func->value->data.function.function_data.pt_type = class_free_;
-    init_func = makeFunctionFromValue(func, func_new, func_init, str_init, obj, obj->value->object.var, inter);
     init_func->value->data.function.function_data.pt_type = object_free_;
 
 

+ 108 - 22
vmcore/ofunc/src/sys.c

@@ -17,7 +17,7 @@ ResultType vm_super(O_FUNC){
     arg_child = ap[1].value->value;
     if (arg_child == arg_father) {
         if (arg_child->object.inherit != NULL){
-            result->value = copyLinkValue(arg_child->object.inherit->value, inter);
+            result->value = COPY_LINKVALUE(arg_child->object.inherit->value, inter);
             result->type = R_opt;
             gc_addTmpLink(&result->value->gc_status);
         } else
@@ -28,7 +28,7 @@ ResultType vm_super(O_FUNC){
     for (Inherit *self_father = arg_child->object.inherit; self_father != NULL; self_father = self_father->next) {
         if (self_father->value->value == arg_father) {
             if (self_father->next != NULL)
-                next_father = copyLinkValue(self_father->next->value, inter);
+                next_father = COPY_LINKVALUE(self_father->next->value, inter);
             break;
         }
     }
@@ -141,7 +141,6 @@ ResultType vm_open(O_FUNC){
 }
 
 ResultType vm_setAssert(O_FUNC, enum AssertRunType type){
-    LinkValue *function_value = NULL;
     setResultCore(result);
     if (arg != NULL) {
         setResultError(E_ArgumentException, MANY_ARG, LINEFILE, true, CNEXT_NT);
@@ -165,6 +164,86 @@ ResultType vm_assertraise(O_FUNC){
     return vm_setAssert(CO_FUNC(arg, var_list, result, belong), assert_raise);
 }
 
+ResultType vm_selfunCore(O_FUNC, bool type){
+    LinkValue *function_value = NULL;
+    ArgumentParser ap[] = {{.type=name_value, .name=L"func", .must=1, .long_arg=false}, {.must=-1}};
+    bool push;
+    setResultCore(result);
+    {
+        parserArgumentUnion(ap, arg, CNEXT_NT);
+        if (!CHECK_RESULT(result))
+            return result->type;
+        freeResult(result);
+    }
+    function_value = ap[0].value;
+    push = function_value->value->data.function.function_data.push;
+    if (push && !type) {  // 原本是push, 现在设定为非push
+        function_value->value->data.function.function_data.push = false;
+        if (function_value->value->object.out_var != NULL)
+            function_value->value->object.out_var = pushVarList(function_value->value->object.out_var, inter);
+    } else if (!push && type){
+        if (function_value->value->object.out_var != NULL)
+            function_value->value->object.out_var = popVarList(function_value->value->object.out_var);
+    }
+
+    result->value = function_value;
+    gc_addTmpLink(&result->value->gc_status);
+    result->type = R_opt;
+    return R_opt;
+}
+
+ResultType vm_selfun(O_FUNC){
+    return vm_selfunCore(CO_FUNC(arg, var_list, result, belong), false);
+}
+
+ResultType vm_nselfun(O_FUNC){
+    return vm_selfunCore(CO_FUNC(arg, var_list, result, belong), true);
+}
+
+ResultType vm_setfreemode(O_FUNC, bool type){
+    setResultCore(result);
+    if (arg != NULL) {
+        setResultError(E_ArgumentException, MANY_ARG, LINEFILE, true, CNEXT_NT);
+        return R_error;
+    }
+
+    inter->data.free_mode = type;
+    setResult(result, inter);
+    return result->type;
+}
+
+ResultType vm_freemode(O_FUNC){
+    return vm_setfreemode(CO_FUNC(arg, var_list, result, belong), true);
+}
+
+ResultType vm_nfreemode(O_FUNC){
+    return vm_setfreemode(CO_FUNC(arg, var_list, result, belong), false);
+}
+
+ResultType vm_opt_mode(O_FUNC, enum OptMode mode){
+    setResultCore(result);
+    if (arg != NULL) {
+        setResultError(E_ArgumentException, MANY_ARG, LINEFILE, true, CNEXT_NT);
+        return R_error;
+    }
+
+    inter->data.opt_mode = mode;
+    setResult(result, inter);
+    return result->type;
+}
+
+ResultType vm_free_opt(O_FUNC){
+    return vm_opt_mode(CO_FUNC(arg, var_list, result, belong), om_free);
+}
+
+ResultType vm_normal_opt(O_FUNC){
+    return vm_opt_mode(CO_FUNC(arg, var_list, result, belong), om_normal);
+}
+
+ResultType vm_simple_opt(O_FUNC){
+    return vm_opt_mode(CO_FUNC(arg, var_list, result, belong), om_simple);
+}
+
 ResultType vm_exec(O_FUNC){
     ArgumentParser ap[] = {{.type=name_value, .name=L"cm", .must=1, .long_arg=false},
                            {.type=name_value, .name=L"var", .must=0, .long_arg=false},
@@ -242,25 +321,32 @@ ResultType vm_exec(O_FUNC){
 }
 
 void registeredSysFunction(R_FUNC){
-    NameFunc tmp[] = {{L"super", vm_super, free_},
-                      {L"freemethod", vm_freemethod, free_},
-                      {L"staticmethod", vm_staticmethod, free_},
-                      {L"staticclassmethod", vm_classmethod, free_},
-                      {L"staticobjectmethod", vm_objectmethod, free_},
-                      {L"classmethod", vm_classfreemethod, free_},
-                      {L"objectmethod", vm_objectfreemethod, free_},
-                      {L"simplemethod", vm_allfreemethod, free_},
-                      {L"simplestaticmethod", vm_allstaticmethod, free_},
-                      {L"clsmethod", vm_clsfreemethod, free_},
-                      {L"clsstaticmethod", vm_clsmethod, free_},
-                      {L"isnowrun", vm_isnowrun, free_},
-                      {L"disnowrun", vm_disnowrun, free_},
-                      {L"quit", vm_quit, free_},
-                      {L"exec", vm_exec, free_},
-                      {L"open", vm_open, free_},
-                      {L"assert_ignore", vm_assertignore, free_},
-                      {L"assert_run", vm_assertrun, free_},
-                      {L"assert_raise", vm_assertraise, free_},
+    NameFunc tmp[] = {{L"super", vm_super, free_, .var=nfv_notpush},
+                      {L"freemethod", vm_freemethod, free_, .var=nfv_notpush},
+                      {L"staticmethod", vm_staticmethod, free_, .var=nfv_notpush},
+                      {L"staticclassmethod", vm_classmethod, free_, .var=nfv_notpush},
+                      {L"staticobjectmethod", vm_objectmethod, free_, .var=nfv_notpush},
+                      {L"classmethod", vm_classfreemethod, free_, .var=nfv_notpush},
+                      {L"objectmethod", vm_objectfreemethod, free_, .var=nfv_notpush},
+                      {L"simplemethod", vm_allfreemethod, free_, .var=nfv_notpush},
+                      {L"simplestaticmethod", vm_allstaticmethod, free_, .var=nfv_notpush},
+                      {L"clsmethod", vm_clsfreemethod, free_, .var=nfv_notpush},
+                      {L"clsstaticmethod", vm_clsmethod, free_, .var=nfv_notpush},
+                      {L"isnowrun", vm_isnowrun, free_, .var=nfv_notpush},
+                      {L"disnowrun", vm_disnowrun, free_, .var=nfv_notpush},
+                      {L"quit", vm_quit, free_, .var=nfv_notpush},
+                      {L"exec", vm_exec, free_, .var=nfv_notpush},
+                      {L"open", vm_open, free_, .var=nfv_notpush},
+                      {L"assert_ignore", vm_assertignore, free_, .var=nfv_notpush},
+                      {L"assert_run", vm_assertrun, free_, .var=nfv_notpush},
+                      {L"assert_raise", vm_assertraise, free_, .var=nfv_notpush},
+                      {L"selfun", vm_selfun, free_, .var=nfv_notpush},
+                      {L"nselfun", vm_nselfun, free_, .var=nfv_notpush},
+                      {L"free_mode", vm_freemode, free_, .var=nfv_notpush},
+                      {L"normal_mode", vm_nfreemode, free_, .var=nfv_notpush},
+                      {L"free_opt", vm_free_opt, free_, .var=nfv_notpush},
+                      {L"normal_opt", vm_normal_opt, free_, .var=nfv_notpush},
+                      {L"simple_opt", vm_simple_opt, free_, .var=nfv_notpush},
                       {NULL, NULL}};
     iterBaseNameFunc(tmp, belong, CFUNC_CORE(var_list));
 }

+ 69 - 72
vmcore/ofunc/src/vobject.c

@@ -1,8 +1,6 @@
 #include "__ofunc.h"
-
-typedef void (*base_opt)(LinkValue *, Result *, struct Inter *, VarList *var_list, Value *, Value *);
-
-void vobject_add_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+typedef void (*base_opt)(FUNC_VOBJ);
+void vobject_add_base(FUNC_VOBJ) {
     setResultCore(result);
     if (left->type == V_int && right->type == V_int)
         makeIntValue(left->data.int_.num + right->data.int_.num, LINEFILE, CNEXT_NT);
@@ -20,7 +18,7 @@ void vobject_add_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         setResultError(E_TypeException, CUL_ERROR(Add), LINEFILE, true, CNEXT_NT);
 }
 
-void vobject_sub_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_sub_base(FUNC_VOBJ) {
     setResultCore(result);
     if (left->type == V_int && right->type == V_int)
         makeIntValue(left->data.int_.num - right->data.int_.num, LINEFILE, CNEXT_NT);
@@ -36,7 +34,7 @@ void vobject_sub_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         setResultError(E_TypeException, CUL_ERROR(Sub), LINEFILE, true, CNEXT_NT);
 }
 
-void vobject_mul_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_mul_base(FUNC_VOBJ) {
     setResultCore(result);
     if (left->type == V_int && right->type == V_int)
         makeIntValue(left->data.int_.num * right->data.int_.num, LINEFILE, CNEXT_NT);
@@ -59,7 +57,7 @@ void vobject_mul_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         setResultError(E_TypeException, CUL_ERROR(Mul), LINEFILE, true, CNEXT_NT);
 }
 
-void vobject_div_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_div_base(FUNC_VOBJ) {
     setResultCore(result);
     if (right->type == V_int && right->data.int_.num == 0 || right->type == V_dou && !(right->data.dou.num != 0))  // !(right->data.dou.num != 0) 因为long double检查是否位0时容易出错
         setResultError(E_TypeException, L"divisor mustn't be 0", LINEFILE, true, CNEXT_NT);
@@ -76,7 +74,7 @@ void vobject_div_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         setResultError(E_TypeException, CUL_ERROR(Div), LINEFILE, true, CNEXT_NT);
 }
 
-void vobject_intdiv_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_intdiv_base(FUNC_VOBJ) {
     setResultCore(result);
     if (right->type == V_int && right->data.int_.num == 0 || right->type == V_dou && (vint)right->data.dou.num == 0)  // !(right->data.dou.num != 0) 因为long double检查是否位0时容易出错
         setResultError(E_TypeException, L"divisor mustn't be 0", LINEFILE, true, CNEXT_NT);
@@ -93,7 +91,7 @@ void vobject_intdiv_base(LinkValue *belong, Result *result, struct Inter *inter,
         setResultError(E_TypeException, CUL_ERROR(Div), LINEFILE, true, CNEXT_NT);
 }
 
-void vobject_mod_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_mod_base(FUNC_VOBJ) {
     setResultCore(result);
     if (right->type == V_int && right->data.int_.num == 0)  // !(right->data.dou.num != 0) 因为long double检查是否位0时容易出错
         setResultError(E_TypeException, L"divisor mustn't be 0", LINEFILE, true, CNEXT_NT);
@@ -104,7 +102,7 @@ void vobject_mod_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         setResultError(E_TypeException, CUL_ERROR(Div), LINEFILE, true, CNEXT_NT);
 }
 
-void vobject_pow_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_pow_base(FUNC_VOBJ) {
     setResultCore(result);
     errno = 0;  // 初始化error
     vdou re;
@@ -126,7 +124,7 @@ void vobject_pow_base(LinkValue *belong, Result *result, struct Inter *inter, Va
         makeDouValue(re, LINEFILE, CNEXT_NT);
 }
 
-void vobject_eq_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_eq_base(FUNC_VOBJ) {
     setResultCore(result);
     if (left->type == V_int && right->type == V_int)
         makeBoolValue(left->data.int_.num == right->data.int_.num, LINEFILE, CNEXT_NT);
@@ -144,7 +142,7 @@ void vobject_eq_base(LinkValue *belong, Result *result, struct Inter *inter, Var
         makeBoolValue(left == right, LINEFILE, CNEXT_NT);
 }
 
-void vobject_noteq_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) {
+void vobject_noteq_base(FUNC_VOBJ) {
     setResultCore(result);
     if (left->type == V_int && right->type == V_int)
         makeBoolValue(left->data.int_.num != right->data.int_.num, LINEFILE, CNEXT_NT);
@@ -162,7 +160,7 @@ void vobject_noteq_base(LinkValue *belong, Result *result, struct Inter *inter,
         makeBoolValue(left != right, LINEFILE, CNEXT_NT);
 }
 
-#define BITMACRO(SYMBOL, NAME, TYPE) void vobject_##NAME##_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) { \
+#define BITMACRO(SYMBOL, NAME, TYPE) void vobject_##NAME##_base(FUNC_VOBJ) { \
     setResultCore(result); \
     if (left->type == V_int && right->type == V_int) \
         makeIntValue(left->data.int_.num SYMBOL right->data.int_.num, LINEFILE, CNEXT_NT); \
@@ -175,7 +173,7 @@ BITMACRO(|, bor, Bit Or)
 BITMACRO(^, bxor, Bit Xor)
 #undef BITMACRO
 
-#define BITMOVEMACRO(SYMBOL1, SYMBOL2, NAME, TYPE) void vobject_##NAME##_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) { \
+#define BITMOVEMACRO(SYMBOL1, SYMBOL2, NAME, TYPE) void vobject_##NAME##_base(FUNC_VOBJ) { \
     setResultCore(result); \
     if (left->type == V_int && right->type == V_int) { \
         if (right->data.int_.num >= 0) \
@@ -190,7 +188,7 @@ BITMOVEMACRO(<<, >>, bl, Bit Left)
 BITMOVEMACRO(>>, <<, br, Bit Right)
 #undef BITMOVEMACRO
 
-#define COMPAREMACRO(SYMBOL, NAME, TYPE) void vobject_##NAME##_base(LinkValue *belong, Result *result, struct Inter *inter, VarList *var_list, Value *left, Value *right) { \
+#define COMPAREMACRO(SYMBOL, NAME, TYPE) void vobject_##NAME##_base(FUNC_VOBJ) { \
     setResultCore(result); \
     if (left->type == V_int && right->type == V_int) \
         makeBoolValue(left->data.int_.num SYMBOL right->data.int_.num, LINEFILE, CNEXT_NT); \
@@ -229,14 +227,11 @@ ResultType vobject_opt_core(O_FUNC, base_opt func){
     left = ap[0].value->value;
     right = ap[1].value->value;
 
-    func(belong, result, inter, var_list, left, right);
+    func(CFUNC_VOBJ(var_list, result, belong, left, right));
     return result->type;
 }
 
-#define COMPAREFUNCMACRO(TYPE) ResultType vobject_##TYPE(O_FUNC){ \
-    return vobject_opt_core(CO_FUNC(arg, var_list, result, belong), vobject_##TYPE##_base); \
-}
-
+#define COMPAREFUNCMACRO(TYPE) ResultType vobject_##TYPE(O_FUNC){ return vobject_opt_core(CO_FUNC(arg, var_list, result, belong), vobject_##TYPE##_base); }
 COMPAREFUNCMACRO(add)
 COMPAREFUNCMACRO(sub)
 COMPAREFUNCMACRO(mul)
@@ -257,19 +252,8 @@ COMPAREFUNCMACRO(bl)
 COMPAREFUNCMACRO(br)
 #undef COMPAREFUNCMACRO
 
-ResultType vobject_negate(O_FUNC){
-    Value *left = NULL;
-    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
-                           {.must=-1}};
+void vobject_negate_base(FUNC_VOBJR) {
     setResultCore(result);
-    {
-        parserArgumentUnion(ap, arg, CNEXT_NT);
-        if (!CHECK_RESULT(result))
-            return result->type;
-        freeResult(result);
-    }
-
-    left = ap[0].value->value;
     switch (left->type) {
         case V_int:
             makeIntValue(-(left->data.int_.num), LINEFILE, CNEXT_NT);
@@ -293,25 +277,13 @@ ResultType vobject_negate(O_FUNC){
             setResultError(E_TypeException, CUL_ERROR(Negate), LINEFILE, true, CNEXT_NT);
             break;
     }
-    return result->type;
 }
 
-ResultType vobject_bnot(O_FUNC){
-    Value *left = NULL;
-    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
-                           {.must=-1}};
+void vobject_bnot_base(FUNC_VOBJR) {
     setResultCore(result);
-    {
-        parserArgumentUnion(ap, arg, CNEXT_NT);
-        if (!CHECK_RESULT(result))
-            return result->type;
-        freeResult(result);
-    }
-
-    left = ap[0].value->value;
     switch (left->type) {
         case V_int:
-            makeIntValue(~(left->data.int_.num), LINEFILE, CNEXT_NT);
+            makeIntValue(~(unsigned long long)(left->data.int_.num), LINEFILE, CNEXT_NT);
             break;
         case V_bool:
             makeBoolValue(!(left->data.bool_.bool_), LINEFILE, CNEXT_NT);
@@ -323,6 +295,31 @@ ResultType vobject_bnot(O_FUNC){
             setResultError(E_TypeException, CUL_ERROR(Negate), LINEFILE, true, CNEXT_NT);
             break;
     }
+}
+
+ResultType vobject_negate(O_FUNC){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CNEXT_NT);
+    if (!CHECK_RESULT(result))
+        return result->type;
+    freeResult(result);
+
+    vobject_negate_base(CFUNC_VOBJR(var_list, result, belong, ap[0].value->value));
+    return result->type;
+}
+
+ResultType vobject_bnot(O_FUNC){
+    ArgumentParser ap[] = {{.type=only_value, .must=1, .long_arg=false},
+                           {.must=-1}};
+    setResultCore(result);
+    parserArgumentUnion(ap, arg, CNEXT_NT);
+    if (!CHECK_RESULT(result))
+        return result->type;
+    freeResult(result);
+
+    vobject_bnot_base(CFUNC_VOBJR(var_list, result, belong, ap[0].value->value));
     return result->type;
 }
 
@@ -447,32 +444,32 @@ ResultType vobject_repo(O_FUNC){
 
 void registeredVObject(R_FUNC){
     LinkValue *object = inter->data.base_obj[B_VOBJECT];
-    NameFunc tmp[] = {{inter->data.mag_func[M_ADD], vobject_add, object_free_},
-                      {inter->data.mag_func[M_SUB], vobject_sub, object_free_},
-                      {inter->data.mag_func[M_MUL], vobject_mul, object_free_},
-                      {inter->data.mag_func[M_DIV], vobject_div, object_free_},
-                      {inter->data.mag_func[M_BOOL], vobject_bool, object_free_},
-                      {inter->data.mag_func[M_REPO], vobject_repo, object_free_},
-                      {inter->data.mag_func[M_STR], vobject_repo, object_free_},
-                      {inter->data.mag_func[M_INTDIV], vobject_intdiv, object_free_},
-                      {inter->data.mag_func[M_MOD], vobject_mod, object_free_},
-                      {inter->data.mag_func[M_POW], vobject_pow, object_free_},
-
-                      {inter->data.mag_func[M_EQ], vobject_eq, object_free_},
-                      {inter->data.mag_func[M_NOTEQ], vobject_noteq, object_free_},
-                      {inter->data.mag_func[M_MOREEQ], vobject_moreeq, object_free_},
-                      {inter->data.mag_func[M_LESSEQ], vobject_lesseq, object_free_},
-                      {inter->data.mag_func[M_MORE], vobject_more, object_free_},
-                      {inter->data.mag_func[M_LESS], vobject_less, object_free_},
-
-                      {inter->data.mag_func[M_BAND], vobject_band, object_free_},
-                      {inter->data.mag_func[M_BOR], vobject_bor, object_free_},
-                      {inter->data.mag_func[M_BXOR], vobject_bxor, object_free_},
-                      {inter->data.mag_func[M_BL], vobject_bl, object_free_},
-                      {inter->data.mag_func[M_BR], vobject_br, object_free_},
-
-                      {inter->data.mag_func[M_NEGATE], vobject_negate, object_free_},
-                      {inter->data.mag_func[M_BNOT], vobject_bnot, object_free_},
+    NameFunc tmp[] = {{inter->data.mag_func[M_ADD], vobject_add, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_SUB], vobject_sub, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_MUL], vobject_mul, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_DIV], vobject_div, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_BOOL], vobject_bool, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_REPO], vobject_repo, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_STR], vobject_repo, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_INTDIV], vobject_intdiv, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_MOD], vobject_mod, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_POW], vobject_pow, object_free_, .var=nfv_notpush},
+
+                      {inter->data.mag_func[M_EQ], vobject_eq, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_NOTEQ], vobject_noteq, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_MOREEQ], vobject_moreeq, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_LESSEQ], vobject_lesseq, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_MORE], vobject_more, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_LESS], vobject_less, object_free_, .var=nfv_notpush},
+
+                      {inter->data.mag_func[M_BAND], vobject_band, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_BOR], vobject_bor, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_BXOR], vobject_bxor, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_BL], vobject_bl, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_BR], vobject_br, object_free_, .var=nfv_notpush},
+
+                      {inter->data.mag_func[M_NEGATE], vobject_negate, object_free_, .var=nfv_notpush},
+                      {inter->data.mag_func[M_BNOT], vobject_bnot, object_free_, .var=nfv_notpush},
                       {NULL, NULL}};
     gc_addTmpLink(&object->gc_status);
     addBaseClassVar(L"vobject", object, belong, inter);

+ 3 - 3
vmcore/src/__run.c

@@ -147,7 +147,7 @@ wchar_t *getNameFromValue(Value *value, int deep, Inter *inter) {
  * @param return_ VarList的返回值
  * @return 是否位yield模式
  */
-bool popYieldVarList(Statement *st, VarList **return_, VarList *out_var, Inter *inter){
+bool popYieldVarList(Statement *st, VarList **return_, VarList *out_var, Inter *inter) {
     bool yield_run;
     if ((yield_run = st->info.have_info)) {
         *return_ = st->info.var_list;
@@ -361,7 +361,7 @@ LinkValue *findAttributes(wchar_t *name, bool free_old, fline line, char *file,
     LinkValue *attr;
     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 = copyLinkValue(attr, inter);
+        attr = COPY_LINKVALUE(attr, inter);
         attr->belong = belong;
     }
     return attr;
@@ -544,7 +544,7 @@ bool checkAut(enum ValueAuthority value, enum ValueAuthority base, fline line, c
 LinkValue *make_new(Inter *inter, LinkValue *belong, LinkValue *class){
     Inherit *object_father = getInheritFromValueCore(class);
     VarList *new_var = copyVarList(class->value->object.out_var, false, inter);
-    Value *new_object = makeObject(inter, NULL, new_var, object_father);
+    Value *new_object = makeObject(inter, NULL, new_var, true, object_father);
     LinkValue *re = makeLinkValue(new_object, belong, auto_aut, inter);
     gc_freeTmpLink(&new_object->gc_status);
     return re;

+ 16 - 12
vmcore/src/inter.c

@@ -1,5 +1,4 @@
 #include "__virtualmath.h"
-#define setName(str) memStrToWcs(str, false)
 
 Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong) {
     Inter *tmp = memCalloc(1, sizeof(Inter));
@@ -49,7 +48,6 @@ Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong) {
     }
 
     registeredFunctionName(tmp, belong);
-    printf("start run gc = %d sec\n", tmp->data.run_gc);
     tmp->data.start_gc = true;
 #if START_GC
     gc_run(tmp, tmp->var_list);
@@ -57,6 +55,7 @@ Inter *makeInter(char *out, char *error_, char *in, LinkValue *belong) {
     return tmp;
 }
 
+#define setName(str) memStrToWcs(str, false)
 void setBaseInterData(struct Inter *inter){
     inter->data.var_name[VN_str] = setName("str_");
     inter->data.var_name[VN_num] = setName("num_");
@@ -73,14 +72,6 @@ void setBaseInterData(struct Inter *inter){
     inter->data.mag_func[M_ENTER] = setName("__enter__");
     inter->data.mag_func[M_EXIT] = setName("__exit__");
     inter->data.mag_func[M_NEW] = setName("__new__");
-    inter->data.mag_func[M_ADD] = setName("+");
-    inter->data.mag_func[M_SUB] = setName("-");
-    inter->data.mag_func[M_MUL] = setName("*");
-    inter->data.mag_func[M_DIV] = setName("/");
-    inter->data.mag_func[M_CALL] = setName("()");
-    inter->data.mag_func[M_DEL] = setName("__del__");
-    inter->data.mag_func[M_DOWN] = setName("[]");
-    inter->data.mag_func[M_SLICE] = setName("[:]");
     inter->data.mag_func[M_ITER] = setName("__iter__");
     inter->data.mag_func[M_NEXT] = setName("__next__");
     inter->data.mag_func[M_REPO] = setName("__repo__");
@@ -90,12 +81,22 @@ void setBaseInterData(struct Inter *inter){
     inter->data.mag_func[M_FATHER] = setName("__father__");
     inter->data.mag_func[M_MESSAGE] = setName("__message__");
     inter->data.mag_func[M_STR] = setName("__str__");
+    inter->data.mag_func[M_DEL] = setName("__del__");
+    inter->data.mag_func[M_ATTR] = setName("__attr__");
+    inter->data.mag_func[M_VAL] = setName("__val__");
+
+    inter->data.mag_func[M_ADD] = setName("+");
+    inter->data.mag_func[M_SUB] = setName("-");
+    inter->data.mag_func[M_MUL] = setName("*");
+    inter->data.mag_func[M_DIV] = setName("/");
+    inter->data.mag_func[M_CALL] = setName("()");
+    inter->data.mag_func[M_DOWN] = setName("[]");
+    inter->data.mag_func[M_SLICE] = setName("[:]");
+
     inter->data.mag_func[M_DOWN_ASSIGMENT] = setName("[]=");
     inter->data.mag_func[M_SLICE_ASSIGMENT] = setName("[:]=");
     inter->data.mag_func[M_DOWN_DEL] = setName("del[]");
     inter->data.mag_func[M_SLICE_DEL] = setName("del[:]");
-    inter->data.mag_func[M_ATTR] = setName("__attr__");
-    inter->data.mag_func[M_VAL] = setName("__val__");
 
     inter->data.mag_func[M_INTDIV] = setName("//");
     inter->data.mag_func[M_MOD] = setName("%");
@@ -126,7 +127,10 @@ void setBaseInterData(struct Inter *inter){
     inter->data.assert_run = assert_raise;
     inter->data.run_gc = 0;
     inter->data.start_gc = false;
+    inter->data.free_mode = false;
+    inter->data.opt_mode = om_normal;
 }
+#undef setName
 
 void freeBaseInterData(struct Inter *inter){
     gc_freeStatementLink(&inter->base_belong->gc_status);

+ 1 - 12
vmcore/src/ofunc.c

@@ -25,17 +25,6 @@ void registeredBaseFunction(struct LinkValue *father, Inter *inter){
         (*list)(CR_FUNC(father, inter->var_list));
 }
 
-void presetting(Inter *inter) {
-    LinkValue *func = inter->data.base_obj[B_FUNCTION];
-    LinkValue *func_new = NULL;
-    LinkValue *func_init = NULL;
-
-    functionPresetting(func, &func_new, &func_init, inter);
-    strFunctionPresetting(func, func_new, func_init, inter);
-
-    functionPresettingLast(func, func_new, func_init, inter);
-}
-
 void registeredFunctionName(Inter *inter, LinkValue *belong){
     makeBaseObject(inter, belong);
 
@@ -56,7 +45,7 @@ void registeredFunctionName(Inter *inter, LinkValue *belong){
     makeBasePointer(inter);
 
     makeBaseStr(inter);
-    presetting(inter);
+    functionPresetting(inter->data.base_obj[B_FUNCTION], inter);
 
     registeredObject(inter->base_belong, CFUNC_CORE(inter->var_list));
     registeredBaseFunction(inter->base_belong, inter);

+ 40 - 15
vmcore/src/runcall.c

@@ -221,6 +221,7 @@ static ResultType callCFunction(LinkValue *func_value, Argument *arg, long int l
     VarList *function_var = NULL;
     OfficialFunction of = NULL;
     Argument *bak;
+    bool push = func_value->value->data.function.function_data.push;
     setResultCore(result);
     gc_addTmpLink(&func_value->gc_status);
 
@@ -229,8 +230,10 @@ static ResultType callCFunction(LinkValue *func_value, Argument *arg, long int l
         goto return_;
 
     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);
-
+    if (push)
+        function_var = pushVarList(func_value->value->object.out_var != NULL ? func_value->value->object.out_var : var_list, inter);
+    else
+        function_var = func_value->value->object.out_var != NULL ? func_value->value->object.out_var : var_list;
     freeResult(result);
     of(CO_FUNC(arg, function_var, result, func_value->belong));  // belong设置为func的belong, 方便权限的认定
     if (result->type == R_func)
@@ -238,7 +241,8 @@ static ResultType callCFunction(LinkValue *func_value, Argument *arg, long int l
     else if (result->type != R_opt && result->type != R_error)
         setResult(result, inter);
 
-    popVarList(function_var);
+    if (push)
+        popVarList(function_var);
     freeFunctionArgument(arg, bak);
 
     return_:
@@ -464,38 +468,60 @@ static void updateFunctionYield(Statement *func_st, Statement *node){
     func_st->info.have_info = true;
 }
 
-static void newFunctionYield(Statement *func_st, Statement *node, VarList *new_var, Inter *inter){
-    new_var->next = NULL;
+static void newFunctionYield(Statement *func_st, Statement *node, bool push, VarList *new_var, Inter *inter){
+    if (push)
+        new_var->next = NULL;
     func_st->info.var_list = new_var;
     func_st->info.node = node->type == yield_code ? node->next : node;
     func_st->info.have_info = true;
+    func_st->info.branch.func.push = push;
 }
 
-static void setFunctionResult(LinkValue *func_value, bool yield_run, Result *result, FUNC_CORE) {
+static void setFunctionResult(LinkValue *func_value, bool yield_run, bool push, Result *result, FUNC_CORE) {
     Statement *st_func = func_value->value->data.function.function;
     if (yield_run) {
         if (result->type == R_yield) {
             updateFunctionYield(st_func, result->node);
             result->type = R_opt;
             result->is_yield = true;
-        } else
-            freeRunInfo(st_func);
+        } else {
+            if (st_func->info.var_list != NULL && push)
+                freeVarList(st_func->info.var_list);
+            setRunInfo(st_func);
+        }
     } else {
         if (result->type == R_yield) {
-            newFunctionYield(st_func, result->node, var_list, inter);
+            newFunctionYield(st_func, result->node, push, var_list, inter);
             result->type = R_opt;
             result->is_yield = true;
-        } else
-            popVarList(var_list);
+        } else {
+            if (push)
+                popVarList(var_list);
+        }
     }
 }
 
+static bool popFuncYieldVarList(Statement *st, VarList **return_, VarList *out_var, bool *push, Inter *inter) {
+    bool yield_run;
+    if ((yield_run = st->info.have_info)) {
+        *push = st->info.branch.func.push;
+        *return_ = st->info.var_list;
+        if (*push)
+            (*return_)->next = out_var;  // 若是push进来的var_list, 则需要重新链接
+    } else if (*push)
+        *return_ = pushVarList(out_var, inter);
+    else
+        *return_ = out_var;
+    return yield_run;
+}
+
 static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int line, char *file, int pt_sep, FUNC_NT) {
     Argument *bak;
     VarList *var_func = NULL;
     Statement *st_func = NULL;
     Parameter *pt_func = func_value->value->data.function.pt;
     bool yield_run = false;
+    bool push = func_value->value->data.function.function_data.push;
     setResultCore(result);
     st_func = func_value->value->data.function.function;
 
@@ -511,8 +537,9 @@ static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int
             out_var = var_list;  // 当out_var等于空的时候为内联函数
         else
             out_var = func_value->value->object.out_var;
-        yield_run = popYieldVarList(st_func, &var_func, out_var, inter);
+        yield_run = popFuncYieldVarList(st_func, &var_func, out_var, &push, inter);
     }
+
     if (yield_run)
         st_func = st_func->info.node;
 
@@ -521,10 +548,8 @@ static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int
         goto return_;
     freeResult(result);
 
-    gc_addTmpLink(&var_func->hashtable->gc_status);
     setParameterCore(line, file, arg, pt_func, var_func, CFUNC_NT(var_list, result, func_value));
     freeFunctionArgument(arg, bak);
-    gc_freeTmpLink(&var_func->hashtable->gc_status);
 
     if (!CHECK_RESULT(result))
         goto return_;
@@ -533,7 +558,7 @@ static ResultType callVMFunction(LinkValue *func_value, Argument *arg, long int
     functionSafeInterStatement(CFUNC(st_func, var_func, result, func_value->belong));  // belong设置为函数的belong,方便权限校对
 
     return_:
-    setFunctionResult(func_value, yield_run, result, CFUNC_CORE(var_func));
+    setFunctionResult(func_value, yield_run, push, result, CFUNC_CORE(var_func));
     gc_freeTmpLink(&func_value->gc_status);
     return result->type;
 }

+ 1 - 1
vmcore/src/runfile.c

@@ -205,7 +205,7 @@ static bool getPackage(LinkValue **imp_value, char *md5_str, char *split, int st
         setResultCore(result);
         *is_new = true;
         imp_inter = deriveInter(belong, inter);
-        pg = makeObject(inter, imp_inter->var_list, copyVarList(var_list, false, inter), NULL);
+        pg = makeObject(inter, imp_inter->var_list, copyVarList(var_list, false, inter), true, NULL);
         if (!is_lock)
             inter->package = makePackage(pg, md5_str, split, inter->package);  // 只有当不是保护读入或私密读入的时才可以记录
         imp_inter->package = inter->package;

+ 49 - 11
vmcore/src/runoperation.c

@@ -1,9 +1,9 @@
 #include "__run.h"
 
 static bool getLeftRightValue(Result *left, Result *right, FUNC);
-static ResultType operationCore(FUNC, wchar_t *name);
-ResultType operationCore2(FUNC, wchar_t *name);
-ResultType assOperation(FUNC);
+static ResultType operationCore(FUNC, wchar_t *name, enum OperationType type);
+static ResultType operationCore2(FUNC, wchar_t *name, enum OperationType type);
+static ResultType assOperation(FUNC);
 ResultType pointOperation(FUNC);
 ResultType blockOperation(FUNC);
 ResultType boolNotOperation(FUNC);
@@ -16,9 +16,8 @@ ResultType boolOperation(FUNC);
  * @param var_list
  * @return
  */
-
-#define OPT_CASE(TYPE) case OPT_##TYPE: operationCore(CNEXT, inter->data.mag_func[M_##TYPE]); break
-#define OPT_CASE2(TYPE) case OPT_##TYPE: operationCore2(CNEXT, inter->data.mag_func[M_##TYPE]); break
+#define OPT_CASE(TYPE) case OPT_##TYPE: operationCore(CNEXT, inter->data.mag_func[M_##TYPE], OPT_##TYPE); break
+#define OPT_CASE2(TYPE) case OPT_##TYPE: operationCore2(CNEXT, inter->data.mag_func[M_##TYPE], OPT_##TYPE); break
 ResultType operationStatement(FUNC) {
     setResultCore(result);
     switch (st->u.operation.OperationType) {
@@ -73,6 +72,7 @@ ResultType operationStatement(FUNC) {
     return result->type;
 }
 #undef OPT_CASE
+#undef OPT_CASE2
 
 static void updateBlockYield(Statement *block_st, Statement *node){
     block_st->info.node = node->type == yield_code ? node->next : node;
@@ -194,7 +194,7 @@ ResultType pointOperation(FUNC) {
     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所属于的对象是否位左值的父亲(若是则需要重新设定belong)
-        result->value = copyLinkValue(result->value, inter);
+        result->value = COPY_LINKVALUE(result->value, inter);
         result->value->belong = left;
     }
 
@@ -686,7 +686,8 @@ bool getLeftRightValue(Result *left, Result *right, FUNC){
     return false;
 }
 
-ResultType operationCore(FUNC, wchar_t *name) {
+#define OPT_CASE(NAME, FUNC_NAME) case OPT_##NAME: vobject_##FUNC_NAME##_base(CFUNC_VOBJ(var_list, result, belong, left.value->value, right.value->value)); break
+static ResultType operationCore(FUNC, wchar_t *name, enum OperationType type) {
     Result left;
     Result right;
     setResultCore(&left);
@@ -695,24 +696,61 @@ ResultType operationCore(FUNC, wchar_t *name) {
 
     if (getLeftRightValue(&left, &right, CNEXT))  // 不需要释放result
         return result->type;
-    runOperationFromValue(left.value, right.value, name, st->line, st->code_file, CNEXT_NT);
+
+    if (IS_BUILTIN_VALUE(left.value->value, inter)) {
+        switch (type) {
+            OPT_CASE(ADD, add);
+            OPT_CASE(SUB, sub);
+            OPT_CASE(MUL, mul);
+            OPT_CASE(DIV, div);
+            OPT_CASE(INTDIV, intdiv);
+            OPT_CASE(MOD, mod);
+            OPT_CASE(POW, pow);
+            OPT_CASE(EQ, eq);
+            OPT_CASE(NOTEQ, noteq);
+            OPT_CASE(MOREEQ, moreeq);
+            OPT_CASE(LESSEQ, lesseq);
+            OPT_CASE(MORE, more);
+            OPT_CASE(LESS, less);
+            OPT_CASE(BAND, band);
+            OPT_CASE(BOR, bor);
+            OPT_CASE(BXOR, bxor);
+            OPT_CASE(BL, bl);
+            OPT_CASE(BR, br);
+            default:
+                goto default_mode;
+        }
+    } else
+        default_mode: runOperationFromValue(left.value, right.value, name, st->line, st->code_file, CNEXT_NT);
 
     freeResult(&left);
     freeResult(&right);
     return result->type;
 }
+#undef OPT_CASE
 
-ResultType operationCore2(FUNC, wchar_t *name) {
+#define OPT_CASE(NAME, FUNC_NAME) case OPT_##NAME: vobject_##FUNC_NAME##_base(CFUNC_VOBJR(var_list, result, belong, left->value)); break
+static ResultType operationCore2(FUNC, wchar_t *name, enum OperationType type) {
     LinkValue *left;
     setResultCore(result);
 
     if (optSafeInterStatement(CFUNC(st->u.operation.left, var_list, result, belong)))
         return result->type;
     GET_RESULTONLY(left, result);  // 不使用freeResult, 不需要多余的把result.value设置为none
-    runOperationFromValue(left, NULL, name, st->line, st->code_file, CNEXT_NT);
+
+    if (IS_BUILTIN_VALUE(left->value, inter)) {
+        switch (type) {
+            OPT_CASE(BNOT, bnot);
+            OPT_CASE(NEGATE, negate);
+            default:
+                goto default_mode;
+        }
+    } else
+        default_mode: runOperationFromValue(left, NULL, name, st->line, st->code_file, CNEXT_NT);
     gc_freeTmpLink(&left->gc_status);
     return result->type;
 }
+#undef OPT_CASE
 
 ResultType runOperationFromValue(LinkValue *self, LinkValue *arg, wchar_t *name, fline line, char *file, FUNC_NT) {
     LinkValue *_func_;

+ 2 - 3
vmcore/src/statement.c

@@ -22,13 +22,12 @@ void setRunInfo(Statement *st){
     st->info.branch.with_._enter_ = NULL;
     st->info.branch.with_.with_belong = NULL;
     st->info.branch.for_.iter = NULL;
+    st->info.branch.func.push = true;
 }
 
 void freeRunInfo(Statement *st) {
-    if (st->info.var_list != NULL) {
-        gc_freeTmpLink(&st->info.var_list->hashtable->gc_status);
+    if (st->info.var_list != NULL)
         freeVarList(st->info.var_list);
-    }
     if (st->info.branch.with_.value != NULL)
         gc_freeTmpLink(&st->info.branch.with_.value->gc_status);
     if (st->info.branch.with_._exit_ != NULL)

+ 43 - 45
vmcore/src/value.c

@@ -1,6 +1,6 @@
 #include "__run.h"
 
-Value *makeObject(Inter *inter, VarList *object, VarList *out_var, Inherit *inherit) {
+Value *makeObject(Inter *inter, VarList *object, VarList *out_var, bool set_out_var, Inherit *inherit) {
     register Value **list_tmp = &inter->base;
     Value *last;
     Value *tmp;
@@ -12,7 +12,7 @@ Value *makeObject(Inter *inter, VarList *object, VarList *out_var, Inherit *inhe
 
     if (inter->data.base_obj[B_OBJECT] != NULL && inherit == NULL)
         inherit = makeInherit(inter->data.base_obj[B_OBJECT]);
-    if (out_var == NULL && inherit != NULL)
+    if (set_out_var && out_var == NULL && inherit != NULL)
         out_var = copyVarList(inherit->value->value->object.out_var, false, inter);
     tmp->object.var = makeObjectVarList(inherit, inter, object);
     tmp->object.out_var = out_var;
@@ -40,9 +40,12 @@ Value *useNoneValue(Inter *inter, Result *result) {
 Value *makeBoolValue(bool bool_num, fline line, char *file, FUNC_NT) {
     Value *tmp = NULL;
     setResultCore(result);
-    callBackCore(inter->data.base_obj[B_BOOL], NULL, line, file, 0, CNEXT_NT);
-    if (!CHECK_RESULT(result))
-        return NULL;
+    if (inter->data.free_mode) {
+        callBackCore(inter->data.base_obj[B_BOOL], NULL, line, file, 0, CNEXT_NT);
+        if (!CHECK_RESULT(result))
+            return NULL;
+    } else
+        setResultOperation(result, boolCore(belong, inter->data.base_obj[B_BOOL], inter));
     tmp = result->value->value;
     tmp->data.bool_.bool_ = bool_num;
     return tmp;
@@ -51,9 +54,12 @@ Value *makeBoolValue(bool bool_num, fline line, char *file, FUNC_NT) {
 Value *makePassValue(fline line, char *file, FUNC_NT){  // TODO-szh 让切片支持该语法 检查语法解析器支持 a[::]的语法
     Value *tmp = NULL;
     setResultCore(result);
-    callBackCore(inter->data.base_obj[B_PASS], NULL, line, file, 0, CNEXT_NT);
-    if (!CHECK_RESULT(result))
-        return NULL;
+    if (inter->data.free_mode) {
+        callBackCore(inter->data.base_obj[B_PASS], NULL, line, file, 0, CNEXT_NT);
+        if (!CHECK_RESULT(result))
+            return NULL;
+    } else
+        setResultOperation(result, passCore(belong, inter->data.base_obj[B_PASS], inter));
     tmp = result->value->value;
     return tmp;
 }
@@ -61,9 +67,12 @@ Value *makePassValue(fline line, char *file, FUNC_NT){  // TODO-szh 让切片支
 Value *makeIntValue(vint num, fline line, char *file, FUNC_NT) {
     Value *tmp = NULL;
     setResultCore(result);
-    callBackCore(inter->data.base_obj[B_INT_], NULL, line, file, 0, CNEXT_NT);
-    if (!CHECK_RESULT(result))
-        return NULL;
+    if (inter->data.free_mode) {
+        callBackCore(inter->data.base_obj[B_INT_], NULL, line, file, 0, CNEXT_NT);
+        if (!CHECK_RESULT(result))
+            return NULL;
+    } else
+        setResultOperation(result, intCore(belong, inter->data.base_obj[B_INT_], inter));
     result->value->belong = belong;
     tmp = result->value->value;
     tmp->data.int_.num = num;
@@ -77,9 +86,12 @@ Value *makeDouValue(vdou num, fline line, char *file, FUNC_NT) {
         setResultError(E_TypeException, L"decimal exception / [inf/nan]", LINEFILE, true, CNEXT_NT);
         return NULL;
     }
-    callBackCore(inter->data.base_obj[B_DOU], NULL, line, file, 0, CNEXT_NT);
-    if (!CHECK_RESULT(result))
-        return NULL;
+    if (inter->data.free_mode) {
+        callBackCore(inter->data.base_obj[B_DOU], NULL, line, file, 0, CNEXT_NT);
+        if (!CHECK_RESULT(result))
+            return NULL;
+    } else
+        setResultOperation(result, douCore(belong, inter->data.base_obj[B_DOU], inter));
     tmp = result->value->value;
     tmp->data.dou.num = num;
     return tmp;
@@ -99,12 +111,13 @@ Value *makePointerValue(void *p, fline line, char *file, FUNC_NT) {
 Value *makeStringValue(wchar_t *str, fline line, char *file, FUNC_NT) {
     Value *tmp = NULL;
     setResultCore(result);
-    callBackCore(inter->data.base_obj[B_STR], NULL, line, file, 0, CNEXT_NT);
-    if (!CHECK_RESULT(result))
-        return NULL;
-
+    if (inter->data.free_mode) {
+        callBackCore(inter->data.base_obj[B_STR], NULL, line, file, 0, CNEXT_NT);
+        if (!CHECK_RESULT(result))
+            return NULL;
+    } else
+        setResultOperation(result, strCore(belong, inter->data.base_obj[B_STR], inter));
     tmp = result->value->value;
-    memFree(tmp->data.str.str);
     tmp->data.str.str = memWidecpy(str);
     return tmp;
 }
@@ -118,16 +131,12 @@ Value *makeVMFunctionValue(Statement *st, Parameter *pt, FUNC_NT) {
     tmp->data.function.function = copyStatement(st);
     tmp->data.function.pt = copyParameter(pt);
     tmp->data.function.function_data.cls = belong;
-    for (VarList *vl = tmp->object.out_var, *vl_next; vl != NULL; vl = vl_next) {
-        vl_next = vl->next;
-        freeVarList(vl);
-    }
     tmp->object.out_var = copyVarList(var_list, false, inter);
     result->value->belong = belong;
     return tmp;
 }
 
-Value *makeCFunctionValue(OfficialFunction of, fline line, char *file, FUNC_NT) {
+Value *makeCFunctionValue(OfficialFunction of, fline line, char *file, bool set_var, bool push, FUNC_NT) {
     Value *tmp = NULL;
     callBackCore(inter->data.base_obj[B_FUNCTION], NULL, line, file, 0, CNEXT_NT);
     if (!CHECK_RESULT(result))
@@ -137,11 +146,13 @@ Value *makeCFunctionValue(OfficialFunction of, fline line, char *file, FUNC_NT)
     tmp->data.function.of = of;
     tmp->data.function.function_data.pt_type = inter->data.default_pt_type;
     tmp->data.function.function_data.cls = belong;
-    for (VarList *vl = tmp->object.out_var, *vl_next; vl != NULL; vl = vl_next) {
-        vl_next = vl->next;
-        freeVarList(vl);
-    }
-    tmp->object.out_var = copyVarList(var_list, false, inter);
+    tmp->data.function.function_data.push = push;
+    if (set_var) {
+        tmp->object.out_var = copyVarList(var_list, false, inter);
+        if (!push)
+            tmp->object.out_var = pushVarList(tmp->object.out_var, inter);
+    } else
+        tmp->object.out_var = NULL;
     result->value->belong = belong;
     return tmp;
 }
@@ -155,18 +166,12 @@ Value *makeFFunctionValue(void (*ffunc)(), fline line, char *file, FUNC_NT) {
     tmp->data.function.type = f_func;
     tmp->data.function.ffunc = ffunc;
     tmp->data.function.function_data.cls = belong;
-    for (VarList *vl = tmp->object.out_var, *vl_next; vl != NULL; vl = vl_next) {
-        vl_next = vl->next;
-        freeVarList(vl);
-    }
-    tmp->object.out_var = copyVarList(var_list, false, inter);
     result->value->belong = belong;
     return tmp;
 }
 
-LinkValue *makeCFunctionFromOf(OfficialFunction of, LinkValue *func, OfficialFunction function_new, OfficialFunction function_init, LinkValue *belong, VarList *var_list, Inter *inter) {
+LinkValue *makeCFunctionFromOf(OfficialFunction of, LinkValue *func, OfficialFunction function_new, LinkValue *belong, VarList *var_list, Inter *inter) {
     Argument *arg = makeValueArgument(func);
-    Argument *init_arg = NULL;
     LinkValue *return_ = NULL;
     Result result;
 
@@ -175,19 +180,12 @@ LinkValue *makeCFunctionFromOf(OfficialFunction of, LinkValue *func, OfficialFun
     return_ = result.value;
     result.value = NULL;
     freeResult(&result);
-
-    init_arg = makeValueArgument(return_);
-    function_init(CO_FUNC(init_arg, func->value->object.var, &result, func));
-    freeResult(&result);
-    freeArgument(init_arg, true);
     freeArgument(arg, true);
 
     return_->value->data.function.type = c_func;
     return_->value->data.function.of = of;
     return_->value->data.function.function_data.pt_type = inter->data.default_pt_type;
     return_->value->data.function.function_data.cls = belong;
-    for (VarList *vl = return_->value->object.out_var; vl != NULL; vl = freeVarList(vl))
-        PASS;
     return_->value->object.out_var = copyVarList(var_list, false, inter);
     return_->belong = belong;
     gc_freeTmpLink(&return_->gc_status);
@@ -197,7 +195,7 @@ LinkValue *makeCFunctionFromOf(OfficialFunction of, LinkValue *func, OfficialFun
 Value *makeClassValue(VarList *var_list, Inter *inter, Inherit *father) {
     Value *tmp;
     VarList *new_var = copyVarList(var_list, false, inter);
-    tmp = makeObject(inter, NULL, new_var, father);
+    tmp = makeObject(inter, NULL, new_var, true, father);
     tmp->type = V_class;
     return tmp;
 }
@@ -605,7 +603,7 @@ bool callDel(Value *object_value, Result *result, Inter *inter, VarList *var_lis
     if (_del_ != NULL){  // TODO-szh 让__del__只运行一次
         gc_addTmpLink(&_del_->gc_status);
         if (_del_->belong != NULL && _del_->belong->value != object_value && checkAttribution(object_value, _del_->belong->value)) {  // 与point运算道理相同
-            _del_ = copyLinkValue(_del_, inter);
+            _del_ = COPY_LINKVALUE(_del_, inter);
             _del_->belong = makeLinkValue(object_value, inter->base_belong, auto_aut, inter);
         }
         callBackCore(_del_, NULL, LINEFILE, 0, CFUNC_NT(var_list, result, inter->base_belong));

+ 6 - 12
vmcore/src/var.c

@@ -226,19 +226,13 @@ VarList *copyVarList(VarList *base, bool n_new, Inter *inter){
     return new;
 }
 
-VarList *connectVarListBack(VarList *base, VarList *back){
-    VarList **tmp = NULL;
-    for (tmp = &base; *tmp != NULL; tmp = &(*tmp)->next)
-        PASS;
-    *tmp = back;
-    return base;
-}
-
 VarList *makeObjectVarList(Inherit *value, Inter *inter, VarList *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);
-    }
+    VarList *next = tmp;
+    assert(tmp != NULL);
+    while (next->next != NULL)
+        next = next->next;
+    for (PASS; value != NULL;next = next->next, value = value->next)
+        next->next = copyVarListCore(value->value->value->object.var, inter);  // 复制一个
     return tmp;
 }