Jelajahi Sumber

feat: 支持在C函数中动态返回af_FuncBody

SongZihuan 3 tahun lalu
induk
melakukan
b6cd0475e4
9 mengubah file dengan 200 tambahan dan 69 penghapusan
  1. 10 1
      include/func.h
  2. 1 1
      include/obj_api.h
  3. 5 3
      src/core/__func.h
  4. 0 3
      src/core/code.c
  5. 19 9
      src/core/env.c
  6. 32 8
      src/core/func.c
  7. 9 11
      src/core/run.c
  8. 123 31
      src/main.c
  9. 1 2
      test/test_env.c

+ 10 - 1
include/func.h

@@ -3,6 +3,7 @@
 typedef struct af_ArgCodeList af_ArgCodeList;
 typedef struct af_ArgList af_ArgList;
 typedef struct af_FuncInfo af_FuncInfo;
+typedef struct af_FuncBody af_FuncBody;
 
 #include "code.h"
 #include "object.h"
@@ -20,7 +21,7 @@ enum af_FuncInfoEmbedded {
     super_embedded,  // 超内嵌函数
 };
 
-typedef void callFuncBody(void *make, af_Environment *env);
+typedef struct af_FuncBody *callFuncBody(void *make, af_Environment *env);
 DEFINE_DLC_SYMBOL(callFuncBody);
 
 /* af_ArgCodeList 创建与释放 */
@@ -45,6 +46,13 @@ af_ArgList **pushNewArgList(af_ArgList **base, char *name, af_Object *obj);
 
 bool runArgList(af_ArgList *al, af_VarSpaceListNode *vsl, af_Environment *env);
 
+/* FuncBody 创建与释放 */
+af_FuncBody *makeCodeFuncBody(af_Code *code, bool free_code, char **msg_type);
+af_FuncBody *makeCFuncBody(DLC_SYMBOL(callFuncBody) c_func, char **msg_type);
+af_FuncBody *makeDynamicFuncBody(void);
+af_FuncBody *freeFuncBody(af_FuncBody *fb);
+void freeAllFuncBody(af_FuncBody *fb);
+
 /* FuncInfo 创建与释放 */
 af_FuncInfo *makeFuncInfo(enum af_FuncInfoScope scope, enum af_FuncInfoEmbedded embedded, bool is_macro, bool var_this, bool var_func);
 
@@ -53,5 +61,6 @@ void freeFuncInfo(af_FuncInfo *fi);
 /* FuncInfo 操作函数 */
 void makeCFuncBodyToFuncInfo(DLC_SYMBOL(callFuncBody) c_func, char **msg_type, af_FuncInfo *fi);
 void makeCodeFuncBodyToFuncInfo(af_Code *code, bool free_code, char **msg_type, af_FuncInfo *fi);
+void makeDynamicFuncBodyToFuncInfo(af_FuncInfo *fi);
 
 #endif //AFUN__FUNC_H_PUBLIC

+ 1 - 1
include/obj_api.h

@@ -21,7 +21,7 @@ typedef void objectAPIFunc();  // 位于object.h (所有Object API函数指针
 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
+typedef struct af_FuncBody *callFuncBody(void *mark, af_Environment *env);  // 位于env.h
 
 /* 定义Object的函数签名 */
 /* Object void *data 管理 */

+ 5 - 3
src/core/__func.h

@@ -2,8 +2,6 @@
 #define AFUN__FUNC_H
 #include "macro.h"
 
-typedef struct af_FuncBody af_FuncBody;
-
 #include "func.h"
 #include "__object.h"
 #include "__code.h"
@@ -26,13 +24,14 @@ struct af_ArgList {
     struct af_ArgList *next;
 };
 
-typedef void callFuncBody(void *mark, af_Environment *env);
+typedef struct af_FuncBody *callFuncBody(void *mark, af_Environment *env);
 NEW_DLC_SYMBOL(callFuncBody, callFuncBody);
 
 struct af_FuncBody {
     enum af_FuncBodyType {
         func_body_c,  // 回调C函数
         func_body_code,  // 执行af_Code
+        func_body_dynamic,
     } type;
 
     union {
@@ -60,4 +59,7 @@ struct af_FuncInfo {
     struct af_FuncBody *body;
 };
 
+/* FuncInfo 操作函数 */
+bool pushDynamicFuncBody(af_FuncBody *new, af_FuncBody *body);
+
 #endif //AFUN__FUNC_H

+ 0 - 3
src/core/code.c

@@ -141,9 +141,6 @@ af_Code *copyCode(af_Code *base, FilePath *path) {
 }
 
 static af_Code *freeCode(af_Code *bt) {
-    if (bt == NULL)
-        return NULL;
-
     af_Code *next = bt->next;
     free(bt->path);
     switch (bt->type) {

+ 19 - 9
src/core/env.c

@@ -785,6 +785,7 @@ bool setFuncActivityAddVar(af_Environment *env){
  * 返回  (0) 表示无下一步
  * 返回 (-1) 表示运行C函数, 并且设置了 process_msg_first
  * 返回  (1) 表示下一步运动Code
+ * 返回  (2) 表示遇到未被替换的动态代码块
  */
 int setFuncActivityToNormal(af_Environment *env){  // 获取函数的函数体
     af_FuncBody *body = env->activity->body_next;
@@ -795,15 +796,24 @@ int setFuncActivityToNormal(af_Environment *env){  // 获取函数的函数体
         return 0;
 
     env->activity->body_next = body->next;
-
-    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;
+    switch (body->type) {
+        case func_body_c: {
+            af_FuncBody *new;
+            new = GET_SYMBOL(body->c_func)(env->activity->mark, env);
+            env->activity->process_msg_first++;  // 处理C函数通过msg_down返回的结果
+            pushDynamicFuncBody(new, body);
+            env->activity->body_next = body->next;  // 添加新元素后要重新设定body_next的位置
+            return -1;
+        }
+        case func_body_code:
+            env->activity->bt_start = body->code;
+            env->activity->bt_next = body->code;
+            return 1;
+        default:
+        case func_body_dynamic:
+            pushMessageDown(makeMessage("ERROR-STR", 0), env);
+            env->activity->process_msg_first++;  // 处理C函数通过msg_down返回的结果
+            return 2;
     }
 }
 

+ 32 - 8
src/core/func.c

@@ -2,10 +2,6 @@
 
 /* FuncBody 创建与释放 */
 static af_FuncBody *makeFuncBody(enum af_FuncBodyType type, char **msg_type);
-static af_FuncBody *makeCodeFuncBody(af_Code *code, bool free_code, char **msg_type);
-static af_FuncBody *makeCFuncBody(DLC_SYMBOL(callFuncBody) c_func, char **msg_type);
-static af_FuncBody *freeFuncBody(af_FuncBody *fb);
-static void freeAllFuncBody(af_FuncBody *fb);
 
 /* msg_type 释放 */
 static void freeMsgType(char **msg_type);
@@ -118,14 +114,19 @@ static af_FuncBody *makeFuncBody(enum af_FuncBodyType type, char **msg_type) {
     return fb;
 }
 
-static af_FuncBody *makeCodeFuncBody(af_Code *code, bool free_code, char **msg_type) {
+af_FuncBody *makeCodeFuncBody(af_Code *code, bool free_code, char **msg_type) {
     af_FuncBody *fb = makeFuncBody(func_body_code, msg_type);
     fb->code = code;
     fb->free_code = free_code;
     return fb;
 }
 
-static af_FuncBody *makeCFuncBody(DLC_SYMBOL(callFuncBody) c_func, char **msg_type) {
+af_FuncBody *makeDynamicFuncBody(void) {
+    af_FuncBody *fb = makeFuncBody(func_body_dynamic, NULL);
+    return fb;
+}
+
+af_FuncBody *makeCFuncBody(DLC_SYMBOL(callFuncBody) c_func, char **msg_type) {
     af_FuncBody *fb = makeFuncBody(func_body_c, msg_type);
     fb->c_func = COPY_SYMBOL(c_func, callFuncBody);
     return fb;
@@ -137,7 +138,7 @@ static void freeMsgType(char **msg_type) {
     free(msg_type);
 }
 
-static af_FuncBody *freeFuncBody(af_FuncBody *fb) {
+af_FuncBody *freeFuncBody(af_FuncBody *fb) {
     af_FuncBody *next = fb->next;
     if (fb->type == func_body_code && fb->free_code)
         freeAllCode(fb->code);
@@ -150,7 +151,7 @@ static af_FuncBody *freeFuncBody(af_FuncBody *fb) {
     return next;
 }
 
-static void freeAllFuncBody(af_FuncBody *fb) {
+void freeAllFuncBody(af_FuncBody *fb) {
     while (fb != NULL)
         fb = freeFuncBody(fb);
 }
@@ -183,3 +184,26 @@ void makeCFuncBodyToFuncInfo(DLC_SYMBOL(callFuncBody) c_func, char **msg_type, a
 void makeCodeFuncBodyToFuncInfo(af_Code *code, bool free_code, char **msg_type, af_FuncInfo *fi) {
     pushFuncBody(&fi->body, makeCodeFuncBody(code, free_code, msg_type));
 }
+
+void makeDynamicFuncBodyToFuncInfo(af_FuncInfo *fi) {
+    pushFuncBody(&fi->body, makeDynamicFuncBody());
+}
+
+bool pushDynamicFuncBody(af_FuncBody *new, af_FuncBody *body) {
+    if (body == NULL || body->next == NULL || body->next->type != func_body_dynamic) {
+        freeAllFuncBody(new);
+        return false;
+    }
+
+    if (new == NULL) {
+        body->next = freeFuncBody(body->next);  // 不添加任何新内容, 但释放func_body_dynamic
+    } else {
+        af_FuncBody **next = &new;
+        while ((*next) != NULL)
+            next = &((*next)->next);
+        *next = freeFuncBody(body->next);  // 把func_body_dynamic后的内容添加到new的末尾
+        body->next = new;
+    }
+
+    return true;
+}

+ 9 - 11
src/core/run.c

@@ -302,17 +302,15 @@ 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 0:  // 已经没有下一步了 (原msg不释放)
-                if (checkMacro(msg, env))  // 检查是否宏函数
-                    break;  // 继续执行
-                checkLiteral(&msg, env);  // 检查是否字面量
-                pushMessageDown(msg, env);
-                return true;
-            default:
-                gc_delReference(*(af_Object **) (msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
-                freeMessage(msg);
-                break;
+        if (setFuncActivityToNormal(env) == 0) {  // 已经没有下一步了
+            if (checkMacro(msg, env))  // 检查是否宏函数
+                return false;  // 继续执行
+            checkLiteral(&msg, env);  // 检查是否字面量
+            pushMessageDown(msg, env);
+            return true;
+        } else {
+            gc_delReference(*(af_Object **) (msg->msg));  // msg->msg是一个指针, 这个指针的内容是一个af_Object *
+            freeMessage(msg);
         }
     } else {
         if (env->activity->bt_next->type == block && env->activity->bt_next->block.type == parentheses &&

+ 123 - 31
src/main.c

@@ -88,7 +88,7 @@ void literalSet(char *str, void *data, af_Object *obj, af_Environment *env) {
     printf("literalSet(): str = %s\n", str);
 }
 
-void testFunc(int *mark, af_Environment *env) {  // 测试用函数
+af_FuncBody *testFunc(int *mark, af_Environment *env) {  // 测试用函数
     printf("testFunc(): I am testFunc\n");
     af_Object *obj;
 
@@ -96,12 +96,13 @@ void testFunc(int *mark, af_Environment *env) {  // 测试用函数
         af_ObjectAPI *api = makeObjectAPI();
         DLC_SYMBOL(objectAPIFunc) literal_set = MAKE_SYMBOL(literalSet, objectAPIFunc);
         if (addAPI(literal_set, "obj_literalSetting", api) != 1)
-            return;
+            return NULL;
         obj = makeObject("func", true, api, true, NULL, NULL, env);
         FREE_SYMBOL(literal_set);
     }
 
     pushMessageDown(makeNORMALMessage(obj), env);
+    return NULL;
 }
 
 bool getInfo(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
@@ -119,7 +120,7 @@ void freeMark(int *mark) {
     free(mark);
 }
 
-void testFunc2(int *mark, af_Environment *env) {  // 测试用函数
+af_FuncBody *testFunc2(int *mark, af_Environment *env) {  // 测试用函数
     printf("testFunc2(): I am testFunc2\n");
     af_Object *obj;
 
@@ -135,23 +136,23 @@ void testFunc2(int *mark, af_Environment *env) {  // 测试用函数
         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;
+            return NULL;
         if (addAPI(initData_2, "obj_initData", api) != 1)
-            return;
+            return NULL;
         if (addAPI(freeData_2, "obj_destructData", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_alc, "obj_funcGetArgCodeList", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_al, "obj_funcGetArgList", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_info, "obj_funcGetInfo", api) != 1)
-            return;
+            return NULL;
         if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
-            return;
+            return NULL;
 
         obj = makeObject("func", true, api, true, NULL, NULL, env);
         FREE_SYMBOL(getSize_2);
@@ -166,6 +167,7 @@ void testFunc2(int *mark, af_Environment *env) {  // 测试用函数
     }
 
     pushMessageDown(makeNORMALMessage(obj), env);
+    return NULL;
 }
 
 bool getInfo2(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
@@ -183,7 +185,7 @@ bool getInfo3(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_En
     return true;
 }
 
-void testFunc4(int *mark, af_Environment *env) {  // 测试用函数
+af_FuncBody *testFunc4(int *mark, af_Environment *env) {  // 测试用函数
     printf("testFunc4(): I am testFunc4\n");
     af_Object *obj;
 
@@ -191,12 +193,13 @@ void testFunc4(int *mark, af_Environment *env) {  // 测试用函数
         af_ObjectAPI *api = makeObjectAPI();
         DLC_SYMBOL(objectAPIFunc) literal_set = MAKE_SYMBOL(literalSet, objectAPIFunc);
         if (addAPI(literal_set, "obj_literalSetting", api) != 1)
-            return;
+            return NULL;
         obj = makeObject("func", true, api, true, NULL, NULL, env);
         FREE_SYMBOL(literal_set);
     }
 
     pushMessageDown(makeNORMALMessage(obj), env);
+    return NULL;
 }
 
 bool getInfo4(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
@@ -207,20 +210,46 @@ 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_FuncBody *testFunc9(int *mark, af_Environment *env) {  // 测试用函数
     af_Object *obj;
-    obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
+    af_FuncBody *fb;
+    obj = makeObject("obj", true, makeObjectAPI(), true, NULL, NULL, env);
+    pushMessageDown(makeNORMALMessage(obj), env);
+    printf("testFunc9(%p): I am testFunc9\n", obj);
+
+    DLC_SYMBOL(callFuncBody) func1 = MAKE_SYMBOL(testFunc9, callFuncBody);
+    fb = makeCFuncBody(func1, NULL);
+    FREE_SYMBOL(func1);
+    
+    return fb;
+}
+
+bool getInfo9(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(testFunc9, callFuncBody);
+    makeCFuncBodyToFuncInfo(func1, NULL, *fi);
+    FREE_SYMBOL(func1);
+
+    makeDynamicFuncBodyToFuncInfo(*fi);
+    return true;
+}
+
+af_FuncBody *testFunc8(int *mark, af_Environment *env) {  // 测试用函数
+    af_Object *obj;
+    obj = makeObject("obj", true, makeObjectAPI(), true, NULL, NULL, env);
     pushMessageDown(makeNORMALMessage(obj), env);
     printf("testFunc8(%p): I am testFunc8\n", obj);
     fflush(stdout);
+    return NULL;
 }
 
-void testFunc7(int *mark, af_Environment *env) {  // 测试用函数
+af_FuncBody *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);
+    return NULL;
 }
 
 bool getInfo7(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
@@ -231,7 +260,7 @@ bool getInfo7(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_En
     return true;
 }
 
-void testFunc6(int *mark, af_Environment *env) {  // 测试用函数
+af_FuncBody *testFunc6(int *mark, af_Environment *env) {  // 测试用函数
     af_Object *obj;
     af_Object *des;
     obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
@@ -245,17 +274,17 @@ void testFunc6(int *mark, af_Environment *env) {  // 测试用函数
         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;
+            return NULL;
         if (addAPI(initData_2, "obj_initData", api) != 1)
-            return;
+            return NULL;
         if (addAPI(freeData_2, "obj_destructData", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_info7, "obj_funcGetInfo", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
-            return;
+            return NULL;
         des = makeObject("func-des", true, api, true, NULL, NULL, env);
         FREE_SYMBOL(get_vsl);
         FREE_SYMBOL(get_info7);
@@ -268,6 +297,7 @@ void testFunc6(int *mark, af_Environment *env) {  // 测试用函数
     setObjectAttributes(gc_destruct, 3, 3, des, obj, env);
     pushMessageDown(makeNORMALMessage(obj), env);
     printf("testFunc6[des](%p, %p): I am testFunc6\n", obj, des);
+    return NULL;
 }
 
 bool getInfo6(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
@@ -282,7 +312,7 @@ bool getInfo6(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_En
     return true;
 }
 
-void testFunc5(int *mark, af_Environment *env) {  // 测试用函数
+af_FuncBody *testFunc5(int *mark, af_Environment *env) {  // 测试用函数
     af_Object *obj;
     af_Object *des;
     obj = makeObject("func", true, makeObjectAPI(), true, NULL, NULL, env);
@@ -296,17 +326,17 @@ void testFunc5(int *mark, af_Environment *env) {  // 测试用函数
         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;
+            return NULL;
         if (addAPI(initData_2, "obj_initData", api) != 1)
-            return;
+            return NULL;
         if (addAPI(freeData_2, "obj_destructData", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_vsl, "obj_funcGetVarList", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_info6, "obj_funcGetInfo", api) != 1)
-            return;
+            return NULL;
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
-            return;
+            return NULL;
         des = makeObject("func-des", true, api, true, NULL, NULL, env);
         FREE_SYMBOL(get_vsl);
         FREE_SYMBOL(get_info6);
@@ -319,6 +349,7 @@ void testFunc5(int *mark, af_Environment *env) {  // 测试用函数
     setObjectAttributes(gc_destruct, 3, 3, des, obj, env);
     pushMessageDown(makeNORMALMessage(obj), env);
     printf("testFunc5(%p, %p): I am testFunc5\n", obj, des);
+    return NULL;
 }
 
 bool getInfo5(af_FuncInfo **fi, af_Object *obj, af_Code *code, void *mark, af_Environment *env) {
@@ -664,6 +695,52 @@ int main() {
         printf("func6(%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_info9 = MAKE_SYMBOL(getInfo9, 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_info9, "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("func7", 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_info9);
+        FREE_SYMBOL(free_mark);
+        FREE_SYMBOL(get_gl);
+        FREE_SYMBOL(getSize_2);
+        FREE_SYMBOL(initData_2);
+        FREE_SYMBOL(freeData_2);
+        printf("func7(%p)\n", obj);
+    }
+
     printf("\n");
 
     {
@@ -918,6 +995,21 @@ int main() {
         printf("\n");
     }
 
+    {  // func_body_dynamic 测试
+        printf("TAG R:\n");
+
+        af_Code *bt2 = makeVariableCode("func7", 0, 1, NULL);
+        af_Code *bt1 = makeBlockCode(curly, bt2, 0, 1, NULL, NULL);
+        af_Code *bt3 = makeVariableCode("global", 0, 1, NULL);
+
+        connectCode(&bt1, bt3);
+
+        iterCode(bt1, env);
+        freeAllCode(bt1);
+        printf("\n");
+    }
+
+    printf("freeEnvironment:\n");
     freeEnvironment(env);
     return 0;
 }

+ 1 - 2
test/test_env.c

@@ -64,7 +64,6 @@ int main() {
 
     {
         af_ObjectAPI *api = makeObjectAPI();
-        af_Object *obj;
         DLC_SYMBOL(objectAPIFunc) getSize_3 = MAKE_SYMBOL(getSize3, objectAPIFunc);
         DLC_SYMBOL(objectAPIFunc) initData_3 = MAKE_SYMBOL(initData3, objectAPIFunc);
         DLC_SYMBOL(objectAPIFunc) freeData_3 = MAKE_SYMBOL(freeData3, objectAPIFunc);
@@ -82,7 +81,7 @@ int main() {
             return 2;
 
         addVarToProtectVarSpace(makeVar("object", 3, 3,
-                                        (obj = makeObject("object", true, api, true, NULL, NULL, env)),
+                                        makeObject("object", true, api, true, NULL, NULL, env),
                                         env),
                                 env);
         FREE_SYMBOL(getSize_3);