Ver código fonte

feat: gc调用析构函数

支持运行时gc检查调用析构
支持运行结束时gc检查调用析构
gc activity不使用msg_up
SongZihuan 3 anos atrás
pai
commit
e9fda15a59
15 arquivos alterados com 598 adições e 242 exclusões
  1. 3 5
      include/env.h
  2. 4 0
      include/gc.h
  3. 2 2
      include/obj_api.h
  4. 4 1
      include/object.h
  5. 1 0
      include/run.h
  6. 1 5
      include/var.h
  7. 19 10
      src/core/__env.h
  8. 16 1
      src/core/__gc.h
  9. 6 3
      src/core/__object.h
  10. 95 44
      src/core/env.c
  11. 137 127
      src/core/gc.c
  12. 22 4
      src/core/object.c
  13. 52 29
      src/core/run.c
  14. 235 10
      src/main.c
  15. 1 1
      test/test_env.c

+ 3 - 5
include/env.h

@@ -8,7 +8,7 @@ typedef struct af_Environment af_Environment;
 typedef struct af_Message af_Message;
 
 /* 顶层消息处理器的处理函数 DLC */
-typedef void TopMsgProcessFunc(af_Message *msg, af_Environment *env);
+typedef void TopMsgProcessFunc(af_Message *msg, bool is_gc, af_Environment *env);
 DEFINE_DLC_SYMBOL(TopMsgProcessFunc);
 
 enum GcRunTime {
@@ -60,8 +60,6 @@ void setEnvVar(char *name, char *data, af_Environment *env);
 char *findEnvVar(char *name, af_Environment *env);
 
 /* 顶层消息处理器管理函数 */
-void addTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
-                      af_Environment *env);
-bool changeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
-                         af_Environment *env);
+void addTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func, af_Environment *env);
+bool changeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func, af_Environment *env);
 #endif //AFUN__ENV_H_PUBLIC

+ 4 - 0
include/gc.h

@@ -4,6 +4,7 @@
 #include "var.h"
 
 typedef struct af_GcList af_GcList;
+typedef struct gc_DestructList gc_DestructList;
 enum af_GcListType {
     glt_obj = 1,
     glt_vs,
@@ -22,6 +23,9 @@ enum af_GcListType {
                                af_Var *: gc_delVarReference, \
                                af_VarSpace *: gc_delVarSpaceReference))(obj))
 
+/* gc_DestructList 释放函数*/
+void freeAllDestructList(gc_DestructList *dl);
+
 /* GcList 操作函数 */
 af_GcList *pushGcList(enum af_GcListType type, void *data, af_GcList *base);
 

+ 2 - 2
include/obj_api.h

@@ -18,7 +18,7 @@
 typedef void objectAPIFunc();  // 位于object.h (所有Object API函数指针都转换为该类型存储, 注: 具体调用类型参见下文)
 
 /* 顶层信号处理器函数 */
-typedef void TopMsgProcessFunc(af_Message *msg, af_Environment *env);  // 位于env.h
+typedef void TopMsgProcessFunc(af_Message *msg, bool is_gc, af_Environment *env);  // 位于env.h
 
 /* 回调C函数 */
 typedef void callFuncBody(void *mark, af_Environment *env);  // 位于env.h
@@ -27,7 +27,7 @@ typedef void callFuncBody(void *mark, af_Environment *env);  // 位于env.h
 /* Object void *data 管理 */
 typedef size_t obj_getDataSize(char *id);  // 获取data的大小
 typedef void obj_initData(char *id, void *data, af_Environment *env);  // 初始化data
-typedef void obj_freeData(char *id, void *data, af_Environment *env);  // 释放data的内容 (但不释放void *data)指针
+typedef void obj_destructData(char *id, void *data, af_Environment *env);  // 释放data的内容 (但不释放void *data)指针
 
 /* Object 面向对象管理 */
 typedef af_VarSpace *obj_getShareVarSpace(af_Object *obj);

+ 4 - 1
include/object.h

@@ -20,9 +20,12 @@ void freeObject(af_Object *obj, af_Environment *env);
 
 /* 对象属性获取函数 */
 void *getObjectData(af_Object *obj);
-af_Object *getBelongObject(af_Object *object, af_Environment *env);
+af_Object *getBelongObject(af_Object *object);
 af_Object *findObjectAttributes(char *name, af_Object *obj);
 
+/* 对象属性设置 */
+bool setObjectAttributes(char *name, char p_self, char p_external, af_Object *attributes, af_Object *obj, af_Environment *env);
+
 /* 对象继承关系函数 */
 af_Inherit *makeInherit(af_Object *obj);
 af_Inherit *freeInherit(af_Inherit *ih);

+ 1 - 0
include/run.h

@@ -5,4 +5,5 @@
 
 /* 代码运行工具 */
 bool iterCode(af_Code *code, af_Environment *env);
+bool iterDestruct(int deep, af_Environment *env);
 #endif //AFUN_RUN_H

+ 1 - 5
include/var.h

@@ -21,13 +21,9 @@ void freeVarSpace(af_VarSpace *vs, af_Environment *env);
 
 /* 变量赋值类函数 */
 bool addVarToVarSpace(af_Var *var, af_VarSpace *vs);
-
 bool makeVarToVarSpace(char *name, char p_self, char p_external, af_Object *obj, af_VarSpace *vs, af_Environment *env);
-
 bool addVarToVarSpaceList(af_Var *var, af_VarSpaceListNode *vsl);
-
-bool makeVarToVarSpaceList(char *name, char p_self, char p_external, af_Object *obj, af_VarSpaceListNode *vsl,
-                           af_Environment *env);
+bool makeVarToVarSpaceList(char *name, char p_self, char p_external, af_Object *obj, af_VarSpaceListNode *vsl, af_Environment *env);
 
 /* 变量寻值类函数 */
 af_Var *findVarFromVarSpace(char *name, af_VarSpace *vs);

+ 19 - 10
src/core/__env.h

@@ -21,9 +21,6 @@ typedef struct af_LiteralDataList af_LiteralDataList;
 #define ENV_VAR_HASH_SIZE (8)
 typedef uint16_t ActivityCount;
 
-typedef void TopMsgProcessFunc(af_Message *msg, af_Environment *env);
-NEW_DLC_SYMBOL(TopMsgProcessFunc, TopMsgProcessFunc);
-
 struct af_Core {  // 解释器核心
     // GC基本信息
     struct af_ObjectData *gc_ObjectData;
@@ -81,18 +78,19 @@ struct af_Activity {  // 活动记录器
 
     struct af_Code *bt_top;  // 最顶层设置为NULL, 函数调用设置为block, (bt_start的上一个元素)
     struct af_Code *bt_start;  // 代码的起始位置 (block的第一个元素)
-    struct af_Code *bt_next;  // 指示代码下一步要运行的位置
+    struct af_Code *bt_next;  // 指示代码下一步要运行的位置 [总是超前当前执行的code]
 
     bool return_first;  // 顺序执行, 获取第一个返回结果
     struct af_Object *return_obj;  // 调用者向被调用者传递信息
+    size_t process_msg_first;  // 优先处理msg而不是code
 
     /* 函数调用专项 */
     enum af_BlockType call_type;  // 函数调用类型
     struct af_Object *parentheses_call;  // 类前缀调用
     struct af_ArgCodeList *acl_start;
-    struct af_ArgCodeList *acl_done;
+    struct af_ArgCodeList *acl_done;  // 记录当前运行的acl [总是与当前执行的acl同步] [acl代码执行完成后需要把结果写入acl, 故不超前]
     struct af_FuncInfo *fi;
-    struct af_FuncBody *body_next;
+    struct af_FuncBody *body_next;  // 下一个需要执行的body [总是超前当前执行的body]
     void *mark;  // 标记 [完全由API管理, 不随activity释放]
     struct af_VarSpaceListNode *macro_vsl;  // 宏函数执行的vsl
     ActivityCount macro_vs_count;
@@ -100,11 +98,20 @@ struct af_Activity {  // 活动记录器
     /* 字面量专项 */
     bool is_literal;  // 处于字面量运算 意味着函数调用结束后会调用指定API
     struct af_LiteralDataList *ld;
+
+    /* gc 机制 */
+    bool is_gc;  // 处于gc的析构函数运行
+    struct gc_DestructList *dl;
+    struct gc_DestructList **pdl;  // 执行dl的最末端
+    struct gc_DestructList *dl_next;  // dl执行的位置
 };
 
+typedef void TopMsgProcessFunc(af_Message *msg, bool is_gc, af_Environment *env);
+NEW_DLC_SYMBOL(TopMsgProcessFunc, TopMsgProcessFunc);
+
 struct af_TopMsgProcess {  // 顶层msg处理器
     char *type;
-    DLC_SYMBOL(TopMsgProcessFunc) func;  // 在 env.h 中定义
+    DLC_SYMBOL(TopMsgProcessFunc) func;
     struct af_TopMsgProcess *next;
 };
 
@@ -123,9 +130,6 @@ struct af_Environment {  // 运行环境
     struct af_EnvVarSpace *esv;
     struct af_Activity *activity;
     struct af_TopMsgProcess *process;
-
-    /* 运行时信息 */
-    bool process_msg_first;  // 优先处理msg而不是运行代码
 };
 
 /* Core 管理函数 */
@@ -140,6 +144,8 @@ bool pushFuncActivity(af_Code *bt, af_Environment *env);
 void popActivity(af_Message *msg, af_Environment *env);
 
 /* 运行时Activity设置函数 (设置Activity) */
+bool pushDestructActivity(gc_DestructList *dl, af_Environment *env);
+void pushGCActivity(gc_DestructList *dl, gc_DestructList **pdl, af_Environment *env);
 bool pushVariableActivity(af_Code *bt, af_Object *func, af_Environment *env);
 bool pushLiteralActivity(af_Code *bt, af_Object *func, af_Environment *env);
 bool pushMacroFuncActivity(af_Object *func, af_Environment *env);
@@ -153,4 +159,7 @@ void freeAllLiteralData(af_LiteralDataList *ld);
 /* LiteralData 操作函数 */
 void pushLiteralData(char *data, af_Environment *env);
 
+/* 顶层消息处理器 处理函数 */
+void runTopMessageProcess(bool is_gc, af_Environment *env);
+
 #endif //AFUN__ENV_H

+ 16 - 1
src/core/__gc.h

@@ -6,6 +6,9 @@ typedef struct GC_Var GC_Var;
 typedef struct GC_VarSpace GC_VarSpace;
 typedef struct GC_Object GC_Object;
 typedef struct GC_ObjectData GC_ObjectData;
+typedef struct af_GcList af_GcList;
+typedef struct gc_Analyzed gc_Analyzed, **pgc_Analyzed;
+typedef struct gc_DestructList gc_DestructList, **pgc_DestructList;
 
 #define GC_FREE_EXCHANGE(obj, Type, Core) do { \
 {if ((obj)->gc.prev != NULL) {(obj)->gc.prev->gc.next = (obj)->gc.next;} \
@@ -24,7 +27,7 @@ struct gc_info {
 struct GC_ObjectData {
     struct gc_info info;
     GC_CHAIN(af_ObjectData);
-    bool done_del;  // 是否已析构
+    bool done_destruct;  // 是否已析构
 };
 
 struct GC_Object {
@@ -62,6 +65,17 @@ struct af_GcList {
     struct af_GcList *next;
 };
 
+struct gc_Analyzed {
+    struct af_Object *obj;
+    struct gc_Analyzed *next;
+};
+
+struct gc_DestructList {
+    struct af_Object *obj;
+    struct af_Object *func;
+    struct gc_DestructList *next;
+};
+
 /* 重新定义包括af_ObjectData的 gc Reference 函数 */
 #undef gc_addReference
 #undef gc_delReference
@@ -92,6 +106,7 @@ void gc_addVarSpaceByCore(struct af_VarSpace *obj, af_Core *core);
 
 /* gc 操控函数 : gc的启动由解释器完全管理 */
 void gc_RunGC(af_Environment *env);
+pgc_DestructList checkAllDestruct(af_Environment *env, pgc_DestructList pdl);
 void gc_freeAllValue(af_Environment *env);
 
 /* gc 信息函数 */

+ 6 - 3
src/core/__object.h

@@ -39,7 +39,7 @@ struct af_ObjectData {
 
     struct af_ObjectAPI *api;  // 继承的api必须位于Inherit链中
     bool allow_inherit;  // 是否允许被继承
-    bool free_api;  // api被继承
+    bool free_api;  // 是否释放api
 
     struct af_VarSpace *var_space;
     struct af_Inherit *inherit;  // 只有顶级继承对象的inherit属性可为NULL
@@ -60,10 +60,13 @@ struct af_Inherit {
     struct af_Inherit *next;
 };
 
-/* ObjectData的释放函数 */
+/* ObjectData 属性获取函数 */
+af_Object *findObjectAttributesByObjectData(char *name, af_ObjectData *od);
+
+/* ObjectData 释放函数 */
 void freeObjectData(af_ObjectData *od, af_Environment *env);
 
-/* Object释放函数 */
+/* Object 释放函数 */
 void freeObjectByCore(af_Object *obj, af_Core *core);
 
 #endif //AFUN__OBJECT_H

+ 95 - 44
src/core/env.c

@@ -1,4 +1,5 @@
 #include "__env.h"
+#include "run.h"
 
 /* Core 创建和释放 */
 static af_Core *makeCore(enum GcRunTime grt);
@@ -32,8 +33,7 @@ static af_TopMsgProcess *freeTopMsgProcess(af_TopMsgProcess *mp);
 static void freeAllTopMsgProcess(af_TopMsgProcess *mp);
 
 /* 顶层消息处理器 处理函数 */
-static void *findTopMsgProcessFunc(char *type, af_Environment *env);
-static void runTopMessageProcess(af_Environment *env);
+static af_TopMsgProcess *findTopMsgProcessFunc(char *type, af_Environment *env);
 
 /* LiteralData 创建与释放 */
 static af_LiteralDataList *makeLiteralDataList(char *data);
@@ -180,6 +180,8 @@ static af_Activity *freeActivity(af_Activity *activity) {
     if (activity->fi != NULL)
         freeFuncInfo(activity->fi);
     freeAllLiteralData(activity->ld);
+    if (activity->dl != NULL)
+        freeAllDestructList(activity->dl);
     free(activity);
     return prev;
 }
@@ -331,13 +333,14 @@ void connectMessage(af_Message **base, af_Message *msg) {
     *base = msg;
 }
 
-void mp_NORMAL(af_Message *msg, af_Environment *env) {
+void mp_NORMAL(af_Message *msg, bool is_gc, af_Environment *env) {
     if (msg->msg == NULL || *(af_Object **)msg->msg == NULL) {
         printf("msg: %p error\n", msg->msg);
         return;
     }
     gc_delReference(*(af_Object **)msg->msg);
-    printf("NORMAL Point: %p\n", *(af_Object **)msg->msg);
+    if (!is_gc)
+        printf("NORMAL Point: %p\n", *(af_Object **)msg->msg);
 }
 
 af_Message *makeNORMALMessage(af_Object *obj) {
@@ -432,6 +435,8 @@ bool enableEnvironment(af_Environment *env) {
 }
 
 void freeEnvironment(af_Environment *env) {
+    if (!env->core->in_init)
+        iterDestruct(10, env);
     freeCore(env);
     freeAllActivity(env->activity);
     freeEnvVarSpace(env->esv);
@@ -463,7 +468,7 @@ static void freeAllTopMsgProcess(af_TopMsgProcess *mp) {
         mp = freeTopMsgProcess(mp);
 }
 
-static void *findTopMsgProcessFunc(char *type, af_Environment *env) {
+static af_TopMsgProcess *findTopMsgProcessFunc(char *type, af_Environment *env) {
     af_TopMsgProcess *mp = env->process;
     for (NULL; mp != NULL; mp = mp->next) {
         if (EQ_STR(type, mp->type))
@@ -490,7 +495,7 @@ bool changeTopMsgProcess(char *type, DLC_SYMBOL(TopMsgProcessFunc) func,
 }
 
 static void newActivity(af_Code *bt, const af_Code *next, bool return_first, af_Environment *env){
-    if (next == NULL && env->activity->body_next == NULL) {
+    if (next == NULL && env->activity->body_next == NULL && !env->activity->is_gc) {
         printf("Tail tone recursive optimization\n");
         clearActivity(env->activity);
         env->activity->bt_top = bt;
@@ -573,7 +578,7 @@ bool pushVariableActivity(af_Code *bt, af_Object *func, af_Environment *env) {
     env->activity->bt_next = bt->next;
 
     /* 隐式调用不设置 bt_top */
-    newActivity(bt, bt->next, false, env);
+    newActivity(NULL, bt->next, false, env);
     return setFuncActivityToArg(func, env);
 }
 
@@ -596,22 +601,64 @@ bool pushMacroFuncActivity(af_Object *func, af_Environment *env) {
     return setFuncActivityToArg(func, env);
 }
 
+void pushGCActivity(gc_DestructList *dl, gc_DestructList **pdl, af_Environment *env) {
+    for (af_Activity *tmp = env->activity; tmp != NULL; tmp = tmp->prev) {
+        if (tmp->is_gc) {
+            *(tmp->pdl) = dl;
+            tmp->pdl = pdl;
+            if (tmp->dl_next == NULL)  // 原dl_next已经运行到末端
+                tmp->dl_next = dl;
+            return;
+        }
+    }
+
+    /* gc Activity 可能创建为顶层 activity, 故信息不能继承上一级(可能没有上一级) */
+    af_Activity *activity = makeActivity(NULL, NULL, false, NULL, NULL, env->core->global, NULL);
+
+    activity->var_list = makeVarSpaceList(getProtectVarSpace(env));
+    activity->vsl = activity->var_list;
+    activity->new_vs_count = 1;
+
+    activity->is_gc = true;
+    activity->dl = dl;
+    activity->pdl = pdl;
+    activity->dl_next = dl;
+
+    activity->prev = env->activity;
+    env->activity = activity;
+}
+
+bool pushDestructActivity(gc_DestructList *dl, af_Environment *env) {
+    env->activity->dl_next = dl->next;
+
+    /* 隐式调用不设置 bt_top */
+    af_Activity *activity = makeActivity(NULL, NULL, false, env->activity->msg_up,
+                                         env->activity->var_list, env->activity->belong, NULL);
+    activity->prev = env->activity;
+    env->activity = activity;
+    return setFuncActivityToArg(dl->func, env);
+}
+
 bool setFuncActivityToArg(af_Object *func, af_Environment *env) {
     obj_funcGetArgCodeList *get_acl = findAPI("obj_funcGetArgCodeList", func->data->api);
     obj_funcGetVarList *get_var_list = findAPI("obj_funcGetVarList", func->data->api);
 
-    if (get_var_list == NULL || get_acl == NULL) {
+    if (get_var_list == NULL) {
         pushMessageDown(makeMessage("ERROR-STR", 0), env);
         return false;
     }
 
     env->activity->func = func;
-    env->activity->belong = getBelongObject(func, env);
+    env->activity->belong = getBelongObject(func);
     env->activity->status = act_arg;
 
     /* 遇到错误时 get_acl 和 get_var_list 要自行设定msg */
-    if (!get_acl(&env->activity->acl_start, func, env->activity->bt_top, &env->activity->mark, env))  // 设置acl
-        return false;
+    if (get_acl != NULL) {
+        if (!get_acl(&env->activity->acl_start, func, env->activity->bt_top, &env->activity->mark, env))  // 设置acl
+            return false;
+    } else
+        env->activity->acl_start = NULL;
+
     if (!get_var_list(&env->activity->func_var_list, func, env->activity->mark, env))  // 设置 func_var_list
         return false;
 
@@ -626,9 +673,8 @@ bool setFuncActivityToArg(af_Object *func, af_Environment *env) {
 bool setFuncActivityAddVar(af_Environment *env){
     obj_funcGetInfo *get_info = findAPI("obj_funcGetInfo", env->activity->func->data->api);
     obj_funcGetArgList *get_arg_list = findAPI("obj_funcGetArgList", env->activity->func->data->api);
-    af_ArgList *al;
 
-    if (get_info == NULL || get_arg_list == NULL) {
+    if (get_info == NULL) {
         pushMessageDown(makeMessage("ERROR-STR", 0), env);
         return false;
     }
@@ -688,57 +734,62 @@ bool setFuncActivityAddVar(af_Environment *env){
         }
     }
 
-    if (!get_arg_list(&al, env->activity->func, env->activity->acl_start, env->activity->mark, env)) {
-        pushMessageDown(makeMessage("ERROR-STR", 0), env);
-        return false;
+    if (get_arg_list != NULL) {
+        af_ArgList *al;
+        if (!get_arg_list(&al, env->activity->func, env->activity->acl_start, env->activity->mark, env)) {
+            pushMessageDown(makeMessage("ERROR-STR", 0), env);
+            return false;
+        }
+        runArgList(al, env->activity->var_list, env);
+        freeAllArgList(al);
     }
-    runArgList(al, env->activity->var_list, env);
-    freeAllArgList(al);
 
     if (env->activity->fi->embedded == protect_embedded)
         env->activity->var_list->vs->is_protect = true;
 
-    int status = setFuncActivityToNormal(env);
-    if (status == -1) {
-        popActivity(makeMessage("ERROR-STR", 0), env);
+    if (setFuncActivityToNormal(env) == 0)
         return false;
-    } else if (status == 0)
-        env->process_msg_first = true;  // 先不弹出activity, 通过act_normal处理msg
     return true;
 }
 
+/*
+ * 函数名: setFuncActivityToNormal
+ * 目标: 获取下一步需要运行的结果
+ * 返回  (0) 表示无下一步
+ * 返回 (-1) 表示运行C函数, 并且设置了 process_msg_first
+ * 返回  (1) 表示下一步运动Code
+ */
 int setFuncActivityToNormal(af_Environment *env){  // 获取函数的函数体
+    af_FuncBody *body = env->activity->body_next;
     env->activity->status = act_normal;
     env->activity->bt_next = NULL;
 
-    if (env->activity->body_next == NULL)  // 已经没有下一步了 (原msg不释放)
-        return -1;
+    if (body == NULL)  // 已经没有下一步了 (原msg不释放)
+        return 0;
 
-    while (env->activity->body_next != NULL) {
-        if (env->activity->body_next->type == func_body_c) {
-            GET_SYMBOL(env->activity->body_next->c_func)(env->activity->mark, env);
-            env->activity->body_next = env->activity->body_next->next;
-        } else {
-            env->activity->bt_start = env->activity->body_next->code;
-            env->activity->bt_next = env->activity->body_next->code;
-            env->activity->body_next = env->activity->body_next->next;
-            return 1;  // 仍有下一步
-        }
-    }
+    env->activity->body_next = body->next;
 
-    return 0;  // 没有下一步, 但运行了C函数 (原msg释放)
+    if (body->type == func_body_c) { /* 运行C函数 */
+        GET_SYMBOL(body->c_func)(env->activity->mark, env);
+        env->activity->process_msg_first++;  // 处理C函数通过msg_down返回的结果
+        return -1;
+    } else {
+        env->activity->bt_start = body->code;
+        env->activity->bt_next = body->code;
+        return 1;
+    }
 }
 
 /*
  * 函数名: runTopMessageProcess
  * 目标: 运行顶层信息处理器
  */
-static void runTopMessageProcess(af_Environment *env) {
+void runTopMessageProcess(bool is_gc, af_Environment *env) {
     af_Message **pmsg = &env->activity->msg_down;
     while (*pmsg != NULL) {
         af_TopMsgProcess *mp = findTopMsgProcessFunc((*pmsg)->type, env);
         if (mp != NULL) {
-            GET_SYMBOL(mp->func)(*pmsg, env);
+            GET_SYMBOL(mp->func)(*pmsg, is_gc, env);
             *pmsg = freeMessage(*pmsg);
         } else
             pmsg = &((*pmsg)->next);
@@ -764,8 +815,6 @@ static void freeMark(af_Environment *env) {
 }
 
 void popActivity(af_Message *msg, af_Environment *env) {
-    env->process_msg_first = true;
-
     if (msg != NULL && env->activity->return_first) {
         if (EQ_STR(msg->type, "NORMAL")) {
             gc_delReference(*(af_Object **) msg->msg);
@@ -792,12 +841,14 @@ void popActivity(af_Message *msg, af_Environment *env) {
 
     freeMark(env);
 
-    if (env->activity->prev != NULL) {
+    if (env->activity->prev == NULL || env->activity->is_gc)  // 顶层或gc层
+        runTopMessageProcess(env->activity->is_gc, env);
+    else {
         connectMessage(&(env->activity->msg_down), env->activity->prev->msg_down);
         env->activity->prev->msg_down = env->activity->msg_down;
         env->activity->msg_down = NULL;
-    } else  // 到顶
-        runTopMessageProcess(env);
+        env->activity->prev->process_msg_first++;  // 优先处理通过msg_down返回的结果
+    }
 
     env->activity = freeActivity(env->activity);
 }

+ 137 - 127
src/core/gc.c

@@ -4,7 +4,73 @@
 #include "__gc.h"
 #include "__env.h"
 
+/* gc 操控函数 */
+#define GC_FUNC_DEFINED(type) \
+void gc_add##type(af_##type *obj, af_Environment *env) { \
+    obj->gc.prev = NULL; \
+    if (env->core->gc_##type != NULL) { \
+        env->core->gc_##type->gc.prev = obj; \
+    }                             \
+    obj->gc.next = env->core->gc_##type; \
+    env->core->gc_##type = obj; \
+} \
+void gc_add##type##ByCore(af_##type *obj, af_Core *core) { \
+if (obj->gc.next != NULL || obj->gc.prev != NULL) {return;} \
+obj->gc.prev = NULL; \
+obj->gc.next = core->gc_##type; \
+core->gc_##type = obj; \
+} \
+void gc_add##type##Reference(af_##type *obj) { \
+    obj->gc.info.reference++; \
+} \
+void gc_del##type##Reference(af_##type *obj) { \
+    obj->gc.info.reference--; \
+}
+
+GC_FUNC_DEFINED(ObjectData)
+GC_FUNC_DEFINED(Object)
+GC_FUNC_DEFINED(Var)
+GC_FUNC_DEFINED(VarSpace)
+
+#undef GC_FUNC_DEFINED
+
+/* gc_DestructList 函数 */
+/* gc_DestructList 创建与释放函数 */
+static gc_DestructList *makeDestructList(af_ObjectData *od, af_Object *func);
+static gc_DestructList *freeDestructList(gc_DestructList *dl);
+
+/* gc_DestructList 操作函数 */
+static pgc_DestructList pushDestructList(af_ObjectData *od, af_Object *func, pgc_DestructList pdl);
+
+static gc_DestructList *makeDestructList(af_ObjectData *od, af_Object *func) {
+    gc_DestructList *dl = calloc(sizeof(gc_DestructList), 1);
+    dl->obj = od->base;
+    dl->func = func;
+    gc_addReference(dl->obj);
+    gc_addReference(dl->func);
+    return dl;
+}
+
+static gc_DestructList *freeDestructList(gc_DestructList *dl) {
+    gc_DestructList *next = dl->next;
+    gc_delReference(dl->obj);
+    gc_delReference(dl->func);
+    free(dl);
+    return next;
+}
+
+void freeAllDestructList(gc_DestructList *dl) {
+    while (dl != NULL)
+        dl = freeDestructList(dl);
+}
+
+static pgc_DestructList pushDestructList(af_ObjectData *od, af_Object *func, pgc_DestructList pdl) {
+    *pdl = makeDestructList(od, func);
+    return &((*pdl)->next);
+}
+
 /* gcList 函数 */
+/* gcList 创建与释放函数 */
 static af_GcList *makeGcList(enum af_GcListType type, void *data);
 static af_GcList *freeGcList(af_GcList *gl);
 static void freeAllGcList(af_GcList *gl);
@@ -33,55 +99,20 @@ af_GcList *pushGcList(enum af_GcListType type, void *data, af_GcList *base) {
     return next;
 }
 
-/* gc 运行时函数 */
-typedef struct gc_Analyzed gc_Analyzed, **pgc_Analyzed;
-struct gc_Analyzed {
-    enum gc_AnalyzedType {
-        gc_ObjectData,
-        gc_Object,
-        gc_Var,
-        gc_VarSpace,
-    } type;
-
-    union {
-        void *data;  // 统一操控指针
-        struct af_ObjectData *od;
-        struct af_Object *obj;
-        struct af_Var *var;
-        struct af_VarSpace *vs;
-    };
-
-    struct gc_Analyzed *next;
-};
-
+/* 分析记录器函数 */
 /* 分析记录器创建与释放函数 */
-static gc_Analyzed *makeAnalyzed(enum gc_AnalyzedType type, void *data);
+static pgc_Analyzed makeAnalyzed(struct af_Object *obj, pgc_Analyzed plist);
 static gc_Analyzed *freeAnalyzed(gc_Analyzed *base);
-
-/* 指定都西昂的分析记录器创建与释放函数 : 调用分析记录器创建与释放函数 */
-static pgc_Analyzed newObjectDataAnalyzed(struct af_ObjectData *od, pgc_Analyzed plist);
-static pgc_Analyzed newObjectAnalyzed(struct af_Object *obj, pgc_Analyzed plist);
-static pgc_Analyzed newVarAnalyzed(struct af_Var *var, pgc_Analyzed plist);
-static pgc_Analyzed newVarSpaceAnalyzed(struct af_VarSpace *vs, pgc_Analyzed plist);
-
-/* 可达性分析函数 */
-static pgc_Analyzed reachableVar(struct af_Var *var, pgc_Analyzed plist);
-static pgc_Analyzed reachableVarSpace(struct af_VarSpace *vs, pgc_Analyzed plist);
-static pgc_Analyzed reachableVarSpaceList(struct af_VarSpaceListNode *vsl, pgc_Analyzed plist);
-static pgc_Analyzed reachableObjectData(struct af_ObjectData *od, pgc_Analyzed plist);
-static pgc_Analyzed reachableObject(struct af_Object *od, pgc_Analyzed plist);
-
-/* gc运行函数 */
-static void freeValue(af_Environment *env);
-static pgc_Analyzed reachable(af_Activity *activity, pgc_Analyzed plist);
-static pgc_Analyzed iterLinker(af_Core *core, pgc_Analyzed plist);
 static void freeAllAnalyzed(gc_Analyzed *base);
 
-static gc_Analyzed *makeAnalyzed(enum gc_AnalyzedType type, void *data) {
-    gc_Analyzed *analyzed = calloc(sizeof(gc_Analyzed), 1);
-    analyzed->type = type;
-    analyzed->data = data;
-    return analyzed;
+// 关于gc_Analyzed为什么只需要记录Object的解释参见下文 (reachableObject)
+static pgc_Analyzed makeAnalyzed(struct af_Object *obj, pgc_Analyzed plist) {
+    if (obj->gc.info.reachable)
+        return plist;
+
+    *plist = calloc(sizeof(gc_Analyzed), 1);
+    (*plist)->obj = obj;
+    return &((*plist)->next);
 }
 
 static gc_Analyzed *freeAnalyzed(gc_Analyzed *base) {
@@ -95,40 +126,27 @@ static void freeAllAnalyzed(gc_Analyzed *base) {
         base = freeAnalyzed(base);
 }
 
-static pgc_Analyzed newObjectDataAnalyzed(struct af_ObjectData *od, pgc_Analyzed plist) {
-    if (od->gc.info.reachable)
-        return plist;
-
-    *plist = makeAnalyzed(gc_ObjectData, od);
-    return &((*plist)->next);
-}
-
-static pgc_Analyzed newObjectAnalyzed(struct af_Object *obj, pgc_Analyzed plist) {
-    if (obj->gc.info.reachable)
-        return plist;
-
-    *plist = makeAnalyzed(gc_Object, obj);
-    return &((*plist)->next);
-}
-
-static pgc_Analyzed newVarAnalyzed(struct af_Var *var, pgc_Analyzed plist) {
-    if (var->gc.info.reachable)
-        return plist;
-
-    *plist = makeAnalyzed(gc_Var, var);
-    return &((*plist)->next);
-}
-
-static pgc_Analyzed newVarSpaceAnalyzed(struct af_VarSpace *vs, pgc_Analyzed plist) {
-    if (vs->gc.info.reachable)
-        return plist;
+/* gc 运行时函数 */
+/* 可达性分析函数 */
+static pgc_Analyzed reachableVar(struct af_Var *var, pgc_Analyzed plist);
+static pgc_Analyzed reachableVarSpace(struct af_VarSpace *vs, pgc_Analyzed plist);
+static pgc_Analyzed reachableVarSpaceList(struct af_VarSpaceListNode *vsl, pgc_Analyzed plist);
+static pgc_Analyzed reachableObjectData(struct af_ObjectData *od, pgc_Analyzed plist);
+static pgc_Analyzed reachableObject(struct af_Object *od, pgc_Analyzed plist);
 
-    *plist = makeAnalyzed(gc_VarSpace, vs);
-    return &((*plist)->next);
-}
+/* gc运行函数 */
+static void freeValue(af_Environment *env);
+static pgc_Analyzed reachable(af_Activity *activity, pgc_Analyzed plist);
+static pgc_Analyzed iterLinker(af_Core *core, pgc_Analyzed plist);
+static pgc_Analyzed checkDestruct(af_Environment *env, pgc_DestructList *pdl, pgc_Analyzed plist);
+static pgc_Analyzed checkAnalyzed(gc_Analyzed *analyzed, pgc_Analyzed plist);
 
 // 使用 gc_Analyzed 目的是令可达性分析程序不需要使用递归
 // Object->OvjectData->VarSpace->Var; 仅允许单项调用, 不发生递归
+// 当VarSpace, Var和ObjectData需要调用Object时, 则使用gc_Analyzed, 创建需要调用的链
+// ObjectData可能要调用API, 因此其需要调用的对象是不确定的, 但只有Object需要gc_Analyzed
+// VarSpace和Var的调用是确定的, 他们不会往回调用除Object外的其他量
+// 所以gc_Analyzed记录Object就足够了
 static pgc_Analyzed reachableObject(struct af_Object *od, pgc_Analyzed plist) {
     for (NULL; od != NULL && !od->gc.info.reachable; od = od->belong) {
         od->gc.info.reachable = true;
@@ -146,11 +164,11 @@ static pgc_Analyzed reachableObjectData(struct af_ObjectData *od, pgc_Analyzed p
     plist = reachableVarSpace(od->var_space, plist);
 
     if (!od->base->gc.info.reachable)
-        plist = newObjectAnalyzed(od->base, plist);
+        plist = makeAnalyzed(od->base, plist);
 
     for (af_Inherit *ih = od->inherit; ih != NULL; ih = ih->next) {
         if (!ih->obj->gc.info.reachable)
-            plist = newObjectAnalyzed(ih->obj, plist);
+            plist = makeAnalyzed(ih->obj, plist);
         if (!ih->vs->gc.info.reachable)
             plist = reachableVarSpace(ih->vs, plist);
     }
@@ -162,7 +180,7 @@ static pgc_Analyzed reachableObjectData(struct af_ObjectData *od, pgc_Analyzed p
             switch (tmp->type) {
                 case glt_obj:
                     if (!tmp->obj->gc.info.reachable)
-                        plist = newObjectAnalyzed(od->base, plist);
+                        plist = makeAnalyzed(od->base, plist);
                     break;
                 case glt_var:
                     plist = reachableVar(tmp->var, plist);
@@ -202,7 +220,7 @@ static pgc_Analyzed reachableVar(struct af_Var *var, pgc_Analyzed plist) {
     var->gc.info.reachable = true;
     for (af_VarNode *vn = var->vn; vn != NULL; vn = vn->next) {
         if (!vn->obj->gc.info.reachable)
-            plist = newObjectAnalyzed(vn->obj, plist);
+            plist = makeAnalyzed(vn->obj, plist);
     }
 
     return plist;
@@ -266,6 +284,12 @@ static pgc_Analyzed reachable(af_Activity *activity, pgc_Analyzed plist) {
     return plist;
 }
 
+static pgc_Analyzed checkAnalyzed(gc_Analyzed *analyzed, pgc_Analyzed plist) {
+    for (gc_Analyzed *done = analyzed; done != NULL; done = done->next)
+        plist = reachableObject(done->obj, plist);
+    return plist;
+}
+
 void resetGC(af_Environment *env) {
     for (af_ObjectData *od = env->core->gc_ObjectData; od != NULL; od = od->gc.next)
         od->gc.info.reachable = false;
@@ -283,7 +307,7 @@ void resetGC(af_Environment *env) {
 static void freeValue(af_Environment *env) {
     for (af_ObjectData *od = env->core->gc_ObjectData, *next; od != NULL; od = next) {
         next = od->gc.next;
-        if (!od->gc.info.reachable) { // 暂时不考虑析构函数
+        if (!od->gc.info.reachable) {
             printf("- gc free ObjectData: %p\n", od);
             freeObjectData(od, env);
         }
@@ -314,70 +338,56 @@ static void freeValue(af_Environment *env) {
     }
 }
 
-#define GC_FUNC_DEFINED(type) \
-void gc_add##type(af_##type *obj, af_Environment *env) { \
-    obj->gc.prev = NULL; \
-    if (env->core->gc_##type != NULL) { \
-        env->core->gc_##type->gc.prev = obj; \
-    }                             \
-    obj->gc.next = env->core->gc_##type; \
-    env->core->gc_##type = obj; \
-} \
-void gc_add##type##ByCore(af_##type *obj, af_Core *core) { \
-if (obj->gc.next != NULL || obj->gc.prev != NULL) {return;} \
-obj->gc.prev = NULL; \
-obj->gc.next = core->gc_##type; \
-core->gc_##type = obj; \
-} \
-void gc_add##type##Reference(af_##type *obj) { \
-    obj->gc.info.reference++; \
-} \
-void gc_del##type##Reference(af_##type *obj) { \
-    obj->gc.info.reference--; \
+static pgc_Analyzed checkDestruct(af_Environment *env, pgc_DestructList *pdl, pgc_Analyzed plist) {
+    for (af_ObjectData *od = env->core->gc_ObjectData; od != NULL; od = od->gc.next) {
+        if (!od->gc.info.reachable && !od->gc.done_destruct) {
+            af_Object *func = findObjectAttributesByObjectData("magic-gc:destruct", od);
+            if (func == NULL)
+                continue;
+            od->gc.done_destruct = true;
+            *pdl = pushDestructList(od, func, *pdl);
+            plist = reachableObjectData(od, plist);
+        }
+    }
+    return plist;
 }
 
-GC_FUNC_DEFINED(ObjectData)
-GC_FUNC_DEFINED(Object)
-GC_FUNC_DEFINED(Var)
-GC_FUNC_DEFINED(VarSpace)
-
-#undef GC_FUNC_DEFINED
-
 void gc_RunGC(af_Environment *env) {
     gc_Analyzed *analyzed = NULL;
+    gc_DestructList *dl = NULL;
     pgc_Analyzed plist = &analyzed;
+    pgc_DestructList pdl = &dl;
     resetGC(env);
 
     plist = iterLinker(env->core, plist);  // 临时量分析 (临时量都是通过reference标记的)
     plist = reachable(env->activity, plist);
-
-    for (gc_Analyzed *done = analyzed; done != NULL; done = done->next) {
-        switch (done->type) {
-            case gc_ObjectData:
-                plist = reachableObjectData(done->od, plist);
-                break;
-            case gc_Object:
-                plist = reachableObject(done->obj, plist);
-                break;
-            case gc_VarSpace:
-                plist = reachableVarSpace(done->vs, plist);
-                break;
-            case gc_Var:
-                plist = reachableVar(done->var, plist);
-                break;
-            default:
-                break;
-        }
-    }
+    plist = checkAnalyzed(analyzed, plist);  // 先处理剩余的Object
+    plist = checkDestruct(env, &pdl, plist);  // 在检查析构
+    checkAnalyzed(analyzed, plist);  // 在处理 checkDestruct 时产生的新引用
 
     freeValue(env);
     freeAllAnalyzed(analyzed);
+    if (dl != NULL)
+        pushGCActivity(dl, pdl, env);
+}
+
+pgc_DestructList checkAllDestruct(af_Environment *env, pgc_DestructList pdl) {
+    for (af_ObjectData *od = env->core->gc_ObjectData; od != NULL; od = od->gc.next) {
+        if (!od->gc.done_destruct) {
+            af_Object *func = findObjectAttributesByObjectData("magic-gc:destruct", od);
+            if (func == NULL)
+                continue;
+            od->gc.done_destruct = true;
+            pdl = pushDestructList(od, func, pdl);
+        }
+    }
+    return pdl;
 }
 
 void gc_freeAllValue(af_Environment *env) {
     for (af_ObjectData *od = env->core->gc_ObjectData, *next; od != NULL; od = next) {
         next = od->gc.next;
-        freeObjectData(od, env);  // 暂时不考虑析构函数
+        freeObjectData(od, env);
     }
 
     for (af_Object *obj = env->core->gc_Object, *next; obj != NULL; obj = next) {

+ 22 - 4
src/core/object.c

@@ -3,8 +3,7 @@
 #include "tool.h"
 
 /* ObjectData 创建与释放 */
-static af_ObjectData *
-makeObjectData_Pri(char *id, bool free_api, af_ObjectAPI *api, bool allow_inherit, af_Environment *env);
+static af_ObjectData *makeObjectData_Pri(char *id, bool free_api, af_ObjectAPI *api, bool allow_inherit, af_Environment *env);
 static af_Object *makeObject_Pri(char *id, bool free_api, af_ObjectAPI *api, bool allow_inherit, af_Environment *env);
 
 /* ObjectData API 创建与释放 */
@@ -100,7 +99,7 @@ af_Object *makeObject(char *id, bool free_api, af_ObjectAPI *api, bool allow_inh
  */
 void freeObjectData(af_ObjectData *od, af_Environment *env) {
     if (od->size != 0) {
-        obj_freeData *func = findAPI("obj_freeData", od->api);
+        obj_destructData *func = findAPI("obj_destructData", od->api);
         if (func != NULL)
             func(od->id, od->data, env);
     }
@@ -128,7 +127,7 @@ void *getObjectData(af_Object *obj) {
     return obj->data->data;
 }
 
-af_Object *getBelongObject(af_Object *object, af_Environment *env) {
+af_Object *getBelongObject(af_Object *object){
     if (object->belong == NULL)
         return object;
     return object->belong;
@@ -284,3 +283,22 @@ af_Object *findObjectAttributes(char *name, af_Object *obj) {
 
     return NULL;
 }
+
+bool setObjectAttributes(char *name, char p_self, char p_external, af_Object *attributes, af_Object *obj, af_Environment *env) {
+    return makeVarToVarSpace(name, p_self, p_external, attributes, obj->data->var_space, env);
+}
+
+af_Object *findObjectAttributesByObjectData(char *name, af_ObjectData *od) {
+    af_Var *var = findVarFromVarSpace(name, od->var_space);
+
+    if (var != NULL)
+        return var->vn->obj;
+
+    for (af_Inherit *ih = od->inherit; ih != NULL; ih = ih->next) {
+        var = findVarFromVarSpace(name, ih->vs);  // 搜索共享变量空间
+        if (var != NULL)
+            return var->vn->obj;
+    }
+
+    return NULL;
+}

+ 52 - 29
src/core/run.c

@@ -107,7 +107,6 @@ static bool checkRunGC(af_Environment *env) {
  * 目标: 初始化activity和environment (若environment中未存在activity则通过code新增一个TopActivity, 否则沿用原activity)
  */
 static bool iterCodeInit(af_Code *code, af_Environment *env) {
-    env->process_msg_first = false;  // 优先处理msg而不是运行代码
     if (env->activity == NULL && code == NULL || env->activity != NULL && code != NULL)
         return false;
     if (code != NULL && !addTopActivity(code, env))  // 初始化环境
@@ -258,21 +257,26 @@ static int checkMsg(af_Message *msg, af_Environment *env) {
  * 返回-false 表示获得msg  (进行实质性运算)
  */
 static bool runCode(af_Message **msg, bool *run_code, af_Environment *env) {
-    bool process_msg_first = env->process_msg_first;
-    env->process_msg_first = false;
-
-    if (env->activity->bt_next == NULL && !process_msg_first) {
+    if (env->activity->bt_next == NULL && env->activity->process_msg_first == 0) {  // 无代码运行, 并且非msg_first
         *run_code = false;
         *msg = NULL;
         return false;
     }
 
-    *run_code = true;
-    if (env->activity->bt_next != NULL && !process_msg_first && runCodeBase(env)) { // runCode返回true, 则代表需要 continue
-        *msg = NULL;
-        return true;  // (该步骤仅为设置Activity, 无实际运算)
+    if (env->activity->process_msg_first == 0) {
+        if (env->activity->bt_next == NULL) {
+            *run_code = false;
+            *msg = NULL;
+            return false;
+        } else if (runCodeBase(env)) {
+            *msg = NULL;
+            return true;  // (该步骤仅为设置Activity, 无实际运算)
+        }
     } else
-        (*msg) = getTopMsg(env);
+        env->activity->process_msg_first--;
+
+    *run_code = true;
+    (*msg) = getTopMsg(env);
 
     switch (checkMsg((*msg), env)) {
         case 0:
@@ -299,24 +303,13 @@ static bool runCode(af_Message **msg, bool *run_code, af_Environment *env) {
 bool checkNormalEnd(af_Message *msg, af_Environment *env) {
     if (env->activity->bt_next == NULL) {
         switch (setFuncActivityToNormal(env)) {
-            case -1:  // 已经没有下一步了 (原msg不释放)
-                if (checkMacro(msg, env))  // 检查是否宏函数
-                    break;  // 继续执行
-                checkLiteral(&msg, env);  // 检查是否字面量
-                pushMessageDown(msg, env);
-                return true;
-            case 0:  // 已经没有下一步了 (但原msg释放)
-                gc_delReference(*(af_Object **) (msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
-                freeMessage(msg);
-
-                msg = getTopMsg(env);
+            case 0:  // 已经没有下一步了 (原msg不释放)
                 if (checkMacro(msg, env))  // 检查是否宏函数
                     break;  // 继续执行
                 checkLiteral(&msg, env);  // 检查是否字面量
                 pushMessageDown(msg, env);
                 return true;
             default:
-            case 1:  // 继续运行
                 gc_delReference(*(af_Object **) (msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
                 freeMessage(msg);
                 break;
@@ -389,15 +382,45 @@ bool iterCode(af_Code *code, af_Environment *env) {
     if (!iterCodeInit(code, env))
         return false;
 
-    for (NULL; env->activity != NULL; checkRunGC(env)) {
+    for (NULL; env->activity != NULL; ) {
         af_Message *msg = NULL;
         bool run_code = false;
+        checkRunGC(env);
 
-        setRunVarSpaceList(env);
-        if (runCode(&msg, &run_code, env))
-            continue;  // 若未获得msg (未进行实质性运算) 则再次运算
-
-        processMsg(msg, run_code, env);
+        if (env->activity->is_gc) {  // gc 模式
+            if (env->activity->dl_next == NULL)
+                popActivity(NULL, env);  // 结束运行
+            else {
+                printf("env->activity->dl_next.obj = %p, %d\n", env->activity->dl_next->obj->data, env->activity->dl_next->obj->data->gc.done_destruct);
+                pushDestructActivity(env->activity->dl_next, env);
+            }
+        } else {
+            setRunVarSpaceList(env);
+            if (runCode(&msg, &run_code, env))
+                continue;  // 若未获得msg (未进行实质性运算) 则再次运算
+            processMsg(msg, run_code, env);
+        }
     }
     return true;
-}
+}
+
+/*
+ * 函数名: iterDestruct
+ * 目标: 对所有ObjectData执行析构函数
+ * 会循环不断检测是否有新增ObjectData并且需要析构
+ * deep - 表示最大迭代深度 (设置为0表示不限制)
+ */
+bool iterDestruct(int deep, af_Environment *env) {
+    for (int count = 0; deep == 0 || deep > count; count++) {
+        gc_DestructList *dl = NULL;
+        pgc_DestructList pdl = &dl;
+
+        pdl = checkAllDestruct(env, pdl);
+        if (dl == NULL)
+            return true;
+        pushGCActivity(dl, pdl, env);
+        if (!iterCode(NULL, env))
+            return false;
+    }
+    return false;
+}

+ 235 - 10
src/main.c

@@ -1,12 +1,14 @@
 #include <stdio.h>
 #include "aFun.h"
 
-void mp_ERROR_STR(af_Message *msg, af_Environment *env) {
+void mp_ERROR_STR(af_Message *msg, bool is_gc, af_Environment *env) {
     char **pinfo = getMessageData(msg);
-    printf("ERROR\n");
+    if (!is_gc)
+        printf("ERROR\n");
     if (pinfo == NULL || *pinfo == NULL)
         return;
-    fprintf(stderr, "ERROR-STR INFO : %s\n", *pinfo);
+    if (!is_gc)
+        fprintf(stderr, "ERROR-STR INFO : %s\n", *pinfo);
     free(*pinfo);
 }
 
@@ -136,7 +138,7 @@ void testFunc2(int *mark, af_Environment *env) {  // 测试用函数
             return;
         if (addAPI(initData_2, "obj_initData", api) != 1)
             return;
-        if (addAPI(freeData_2, "obj_freeData", api) != 1)
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
             return;
         if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
             return;
@@ -205,6 +207,129 @@ bool getInfo4(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_En
     return true;
 }
 
+void testFunc8(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc8(%p): I am testFunc8\n", obj);
+    fflush(stdout);
+}
+
+void testFunc7(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc7[des](%p): I am testFunc7\n", obj);
+    fflush(stdout);
+}
+
+bool getInfo7(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc7, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    return true;
+}
+
+void testFunc6(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    af_Object *des;
+    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info7 = MAKE_SYMBOL(getInfo7, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return;
+        if (addAPI(get_info7, "obj_funcGetInfo", api) != 1)
+            return;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return;
+        des = makeObject("func-des", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_info7);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+    }
+
+    setObjectAttributes("magic-gc:destruct", 3, 3, des, obj, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc6[des](%p, %p): I am testFunc6\n", obj, des);
+}
+
+bool getInfo6(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func1 = MAKE_SYMBOL(testFunc6, callFuncBody);
+    makeCFuncBodyToFuncInfo(func1, NULL, *fi);
+    FREE_SYMBOL(func1);
+
+    DLC_SYMBOL(callFuncBody) func2 = MAKE_SYMBOL(testFunc8, callFuncBody);
+    makeCFuncBodyToFuncInfo(func2, NULL, *fi);
+    FREE_SYMBOL(func2);
+    return true;
+}
+
+void testFunc5(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    af_Object *des;
+    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info6 = MAKE_SYMBOL(getInfo6, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return;
+        if (addAPI(get_info6, "obj_funcGetInfo", api) != 1)
+            return;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return;
+        des = makeObject("func-des", true, api, true, NULL, NULL, env);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_info6);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+    }
+
+    setObjectAttributes("magic-gc:destruct", 3, 3, des, obj, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc5(%p, %p): I am testFunc5\n", obj, des);
+}
+
+bool getInfo5(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
+    *fi = makeFuncInfo(normal_scope, not_embedded, false, true, true);
+    DLC_SYMBOL(callFuncBody) func = MAKE_SYMBOL(testFunc5, callFuncBody);
+    makeCFuncBodyToFuncInfo(func, NULL, *fi);
+    FREE_SYMBOL(func);
+    makeCodeFuncBodyToFuncInfo(makeVariableCode("test", NUL, 0, "Unknow"), true, NULL, *fi);
+    return true;
+}
+
 bool objFunc(af_Object *obj) {
     return true;
 }
@@ -224,7 +349,7 @@ int main() {
             return 2;
         if (addAPI(initData_, "obj_initData", api) != 1)
             return 2;
-        if (addAPI(freeData_, "obj_freeData", api) != 1)
+        if (addAPI(freeData_, "obj_destructData", api) != 1)
             return 2;
 
         addVarToProtectVarSpace(makeVar("global", 3, 3,
@@ -248,7 +373,7 @@ int main() {
             return 2;
         if (addAPI(initData_3, "obj_initData", api) != 1)
             return 2;
-        if (addAPI(freeData_3, "obj_freeData", api) != 1)
+        if (addAPI(freeData_3, "obj_destructData", api) != 1)
             return 2;
         if (addAPI(getShareVS_, "obj_getShareVarSpace", api) != 1)
             return 2;
@@ -283,7 +408,7 @@ int main() {
             return 2;
         if (addAPI(initData_2, "obj_initData", api) != 1)
             return 2;
-        if (addAPI(freeData_2, "obj_freeData", api) != 1)
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
             return 2;
         if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
             return 2;
@@ -329,7 +454,7 @@ int main() {
             return 2;
         if (addAPI(initData_2, "obj_initData", api) != 1)
             return 2;
-        if (addAPI(freeData_2, "obj_freeData", api) != 1)
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
             return 2;
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
             return 2;
@@ -375,7 +500,7 @@ int main() {
             return 2;
         if (addAPI(initData_2, "obj_initData", api) != 1)
             return 2;
-        if (addAPI(freeData_2, "obj_freeData", api) != 1)
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
             return 2;
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
             return 2;
@@ -422,7 +547,7 @@ int main() {
             return 2;
         if (addAPI(initData_2, "obj_initData", api) != 1)
             return 2;
-        if (addAPI(freeData_2, "obj_freeData", api) != 1)
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
             return 2;
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
             return 2;
@@ -455,6 +580,90 @@ int main() {
         printf("func4(%p)\n", obj);
     }
 
+    {
+        af_ObjectAPI *api = makeObjectAPI();
+        af_Object *obj;
+        DLC_SYMBOL(objectAPIFunc) get_alc = MAKE_SYMBOL(getAcl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_al = MAKE_SYMBOL(getAl, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_info5 = MAKE_SYMBOL(getInfo5, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) free_mark = MAKE_SYMBOL(freeMark, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+        DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+        if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+            return 2;
+        if (addAPI(initData_2, "obj_initData", api) != 1)
+            return 2;
+        if (addAPI(freeData_2, "obj_destructData", api) != 1)
+            return 2;
+        if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
+            return 2;
+        if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+            return 2;
+        if (addAPI(get_al, "obj_funcGetArgList", api) != 1)
+            return 2;
+        if (addAPI(get_info5, "obj_funcGetInfo", api) != 1)
+            return 2;
+        if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
+            return 2;
+        if (addAPI(get_gl, "obj_getGcList", api) != 1)
+            return 2;
+
+        addVarToProtectVarSpace(makeVar("func5", 3, 3,
+                                        (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
+                                env);
+        FREE_SYMBOL(get_alc);
+        FREE_SYMBOL(get_vsl);
+        FREE_SYMBOL(get_al);
+        FREE_SYMBOL(get_info5);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func5(%p)\n", obj);
+    }
+
+    {
+        af_Object *obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+        af_Object *des;
+
+        {
+            af_ObjectAPI *api = makeObjectAPI();
+            DLC_SYMBOL(objectAPIFunc) get_vsl = MAKE_SYMBOL(getVsl, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) get_info6 = MAKE_SYMBOL(getInfo6, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) get_gl = MAKE_SYMBOL(getGcList, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) getSize_2 = MAKE_SYMBOL(getSize2, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) initData_2 = MAKE_SYMBOL(initData2, objectAPIFunc);
+            DLC_SYMBOL(objectAPIFunc) freeData_2 = MAKE_SYMBOL(freeData2, objectAPIFunc);
+            if (addAPI(getSize_2, "obj_getDataSize", api) != 1)
+                return 2;
+            if (addAPI(initData_2, "obj_initData", api) != 1)
+                return 2;
+            if (addAPI(freeData_2, "obj_destructData", api) != 1)
+                return 2;
+            if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
+                return 2;
+            if (addAPI(get_info6, "obj_funcGetInfo", api) != 1)
+                return 2;
+            if (addAPI(get_gl, "obj_getGcList", api) != 1)
+                return 2;
+            des = makeObject("func-des", true, api, true, NULL, NULL, env);
+            FREE_SYMBOL(get_vsl);
+            FREE_SYMBOL(get_info6);
+            FREE_SYMBOL(get_gl);
+            FREE_SYMBOL(getSize_2);
+            FREE_SYMBOL(initData_2);
+            FREE_SYMBOL(freeData_2);
+        }
+
+        setObjectAttributes("magic-gc:destruct", 3, 3, des, obj, env);
+        addVarToProtectVarSpace(makeVar("func6", 3, 3, obj, env), env);
+        printf("func6(%p)\n", obj);
+    }
+
     printf("\n");
 
     {
@@ -693,6 +902,22 @@ int main() {
         printf("\n");
     }
 
+    {  // 函数调用
+        printf("TAG P:\n");
+
+        af_Code *bt2 = makeVariableCode("func5", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(curly, bt2, 0, 1, NULL, NULL);
+        af_Code *bt3 = makeVariableCode("global", 0, 1, NULL);
+        af_Code *bt4 = makeVariableCode("global", 0, 1, NULL);
+
+        connectCode(&bt1, bt3);
+        connectCode(&bt3, bt4);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
     freeEnvironment(env);
     return 0;
 }

+ 1 - 1
test/test_env.c

@@ -28,7 +28,7 @@ int main() {
             return 2;
         if (addAPI(initData_, "obj_initData", api) != 1)
             return 2;
-        if (addAPI(freeData_, "obj_freeData", api) != 1)
+        if (addAPI(freeData_, "obj_destructData", api) != 1)
             return 2;
 
         addVarToProtectVarSpace(makeVar("global", 3, 3,