瀏覽代碼

refactor: 重构了activity模块

重新设计activity模块
添加gc宏
修改Code结构体内容
修改Var对被保护变量空间的支持
SongZihuan 3 年之前
父節點
當前提交
b0af802916
共有 8 個文件被更改,包括 198 次插入56 次删除
  1. 1 0
      include/code.h
  2. 3 4
      include/env.h
  3. 3 0
      include/gc.h
  4. 2 1
      src/core/__code.h
  5. 23 6
      src/core/__env.h
  6. 27 17
      src/core/code.c
  7. 136 28
      src/core/env.c
  8. 3 0
      src/core/var.c

+ 1 - 0
include/code.h

@@ -18,6 +18,7 @@ af_Code *copyCode(af_Code *base, FilePath *path);
 af_Code *freeCode(af_Code *bt);
 bool freeCodeWithElement(af_Code *bt, af_Code **next);
 void freeAllCode(af_Code *bt);
+bool getCodeBlockNext(af_Code *bt, af_Code **next);
 bool writeAllCode(af_Code *bt, FILE *file);
 bool readAllCode(af_Code **bt, FILE *file);
 void printCode(af_Code *bt);

+ 3 - 4
include/env.h

@@ -13,17 +13,16 @@ af_Object *getBaseObject(char *name, af_Environment *env);
 af_Environment *makeEnvironment(void);
 bool enableEnvironment(af_Code *bt, af_Environment *env);
 void freeEnvironment(af_Environment *env);
-void pushActivity(af_Code *bt, bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong,
-                  af_Environment *env);
-void popActivity(af_Environment *env);
 
 af_Message *makeMessage(char *type, size_t size);
 af_Message *freeMessage(af_Message *msg);
 void freeAllMessage(af_Message *msg);
 void pushMessageUp(af_Message *msg, af_Environment *env);
 void pushMessageDown(af_Message *msg, af_Environment *env);
-af_Message *popMessageUp(char *type, af_Environment *env);
+void *popMessageUp(char *type, af_Environment *env);
+void *getMessageData(af_Message *msg);
 af_Message *popMessageDown(char *type, af_Environment *env);
+void connectMessage(af_Message **base, af_Message *msg);
 
 void setEnvVar(char *name, char *data, af_Environment *env);
 char *findEnvVar(char *name, af_Environment *env);

+ 3 - 0
include/gc.h

@@ -3,6 +3,9 @@
 #include "object.h"
 #include "var.h"
 
+#define gc_addReference(obj) ((obj)->gc.info.reference++)
+#define gc_delReference(obj) ((obj)->gc.info.reference--)
+
 void gc_addObject(af_Object *obj, af_Environment *env);
 void gc_addVar(af_Var *obj, af_Environment *env);
 void gc_addVarSpace(af_VarSpace *obj, af_Environment *env);

+ 2 - 1
src/core/__code.h

@@ -1,5 +1,5 @@
 /*
- * 文件名: __bytecode.h
+ * 文件名: __code.h
  * 目标: 定义Code结构体
  */
 
@@ -32,6 +32,7 @@ struct af_Code {  // 一个 Code 的结构体
 
         struct {
             CodeUint elements;  // 元素个数
+            CodeUint count;  // 总元素个数
             enum af_BlockType type;  // 括号类型
         } block;
     };

+ 23 - 6
src/core/__env.h

@@ -42,17 +42,29 @@ struct af_Message {
 struct af_Activity {  // 活动记录器
     struct af_Activity *prev;  // 上一个活动记录器
 
+    enum af_ActivityStatus {
+        act_func = 0,
+        act_arg,
+        act_normal,
+    } status;
+
     struct af_Message *msg_down;  // 被调用者向调用者传递信息
     struct af_Message *msg_up;  // 调用者向被调用者传递信息
-
-    struct af_Code *bt_start;  // 代码的起始位置
-    struct af_Code *bt;  // 指示代码运行的地方
+    ActivityCount msg_up_count;  // msg_up 添加的个数
+    char **msg_type;  // 一个包含字符串的列表, 记录了需要处理的`msg`类型的数组
 
     struct af_VarSpaceListNode *var_list;  // 变量空间
     ActivityCount new_vs_count;  // 需要释放的空间数
 
-    struct af_Object *belong;  // 属对象
-    bool is_top;  // 最顶层
+    struct af_Object *belong;  // 属对象 (belong通常为func的belong)
+    struct af_Object *func;  // 函数本身
+
+    struct af_Code *bt_top;  // 最顶层设置为NULL, 函数调用设置为block, (bt_start的上一个元素)
+    struct af_Code *bt_start;  // 代码的起始位置 (block的第一个元素)
+    struct af_Code *bt_next;  // 指示代码下一步要运行的位置
+
+    bool return_first;  // 顺序执行, 获取第一个返回结果
+    struct af_Message *return_msg;  // 调用者向被调用者传递信息
 };
 
 struct af_EnvVar {  // 环境变量
@@ -72,5 +84,10 @@ struct af_Environment {  // 运行环境
 };
 
 af_Object *getBaseObjectFromCore(char *name, af_Core *core);
-
+bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env);
+bool pushFuncActivity(af_Code *bt, af_Environment *env);
+void popActivity(af_Message *msg, af_Environment *env);
+bool setFuncActivityToArg(af_Object *func, af_Environment *env);
+bool setFuncActivityAddVar(af_VarSpaceListNode *vsl, bool new_vsl, bool is_protect, char **msg_type, af_Environment *env);
+bool setFuncActivityToNormal(af_Code *bt, af_Environment *env);
 #endif //AFUN__ENV_H

+ 27 - 17
src/core/code.c

@@ -1,12 +1,12 @@
 /*
- * 文件名: bytecode.c
+ * 文件名: code.c
  * 目标: 管理Code结构体的函数
  */
 
 #include <stdio.h>
 #include "aFun.h"
-#include "__code.h"
 #include "tool.h"
+#include "__code.h"
 
 static af_Code *makeCode(char prefix, FileLine line, FilePath path) {
     af_Code *bt = calloc(1, sizeof(af_Code));
@@ -37,12 +37,13 @@ af_Code *makeVariableCode(char *var, char prefix, FileLine line, FilePath path)
  * 函数名: countElement
  * 目标: 统计元素个数(不包括元素的子元素)
  */
-static bool countElement(af_Code *element, CodeUint *count, af_Code **next) {
+static bool countElement(af_Code *element, CodeUint *elements, CodeUint *count, af_Code **next) {
     CodeUint to_next = 0;  // 表示紧接着的元素都不纳入统计(指block的子元素)
 
-    for (*count = 0; element != NULL; *next = element, element = element->next) {
+    for (*elements = 0; element != NULL; *next = element, element = element->next) {
+        (*count)++;
         if (to_next == 0)
-            (*count)++;
+            (*elements)++;
         else
             to_next--;
 
@@ -50,7 +51,7 @@ static bool countElement(af_Code *element, CodeUint *count, af_Code **next) {
             to_next += element->block.elements;
     }
 
-    if (to_next != 0)
+    if (to_next != 0 || *elements == 0)  // elements不允许为0
         return false;
     return true;
 }
@@ -58,18 +59,20 @@ static bool countElement(af_Code *element, CodeUint *count, af_Code **next) {
 af_Code *makeBlockCode(enum af_BlockType type, af_Code *element, char prefix, FileLine line, FilePath path, af_Code **next) {
     af_Code *bt = NULL;
     af_Code *tmp = NULL;
+    CodeUint elements = 0;
     CodeUint count = 0;
 
     if (next == NULL)
         next = &tmp;
 
-    if (!countElement(element, &count, next))
+    if (!countElement(element, &elements, &count, next))
         return NULL;
 
     bt = makeCode(prefix, line, path);
     bt->type = block;
     bt->block.type = type;
-    bt->block.elements = count;
+    bt->block.elements = elements;
+    bt->block.count = count;
     bt->next = element;
     return bt;
 }
@@ -103,6 +106,7 @@ af_Code *copyCode(af_Code *base, FilePath *path) {
                 break;
 
             case block:
+                (*pdest)->block.count = base->block.count;
                 (*pdest)->block.elements = base->block.elements;
                 (*pdest)->block.type = base->block.type;
                 break;
@@ -143,15 +147,12 @@ af_Code *freeCode(af_Code *bt) {
 }
 
 bool freeCodeWithElement(af_Code *bt, af_Code **next) {
-    CodeUint count = 1;  // 要释放的元素个数
+    CodeUint count = 1 + bt->block.count;  // 要释放的元素个数
     for (NULL; count != 0; count--) {
         if (bt == NULL)
             return false;
-        if (bt->type == block)
-            count += bt->block.elements;
         bt = freeCode(bt);
     }
-
     *next = bt;
     return true;
 }
@@ -161,6 +162,16 @@ void freeAllCode(af_Code *bt) {
         bt = freeCode(bt);
 }
 
+bool getCodeBlockNext(af_Code *bt, af_Code **next) {
+    CodeUint count = 1 + bt->block.count;
+    for (NULL; count != 0; count--, bt = bt->next) {
+        if (bt == NULL)
+            return false;
+    }
+    *next = bt;
+    return true;
+}
+
 #define Done(write) do{if(!(write)){return false;}}while(0)
 
 static bool writeCode(af_Code *bt, FILE *file) {
@@ -186,6 +197,7 @@ static bool writeCode(af_Code *bt, FILE *file) {
         case block:
             Done(byteWriteUint_8(file, bt->block.type));
             Done(byteWriteUint_32(file, bt->block.elements));
+            Done(byteWriteUint_32(file, bt->block.count));
             break;
         default:
             break;
@@ -246,10 +258,13 @@ static bool readCode(af_Code **bt, FILE *file) {
         case block: {
             uint8_t block_type;
             uint32_t elements;
+            uint32_t count;
             Done(byteReadUint_8(file, &block_type));
             Done(byteReadUint_32(file,&elements));
+            Done(byteReadUint_32(file,&count));
             (*bt)->block.type = block_type;
             (*bt)->block.elements = elements;
+            (*bt)->block.elements = count;
             break;
         }
         default:
@@ -258,11 +273,6 @@ static bool readCode(af_Code **bt, FILE *file) {
     return true;
 }
 
-/*
- * 函数名: writeAllCode
- * 目标: 将Code写入字节码文件中
- * 备注: 写入字节码时不做语义检查, 在读取时最语义检查即可 【语义检查还未实现】
- */
 bool readAllCode(af_Code **bt, FILE *file) {
     uint32_t count;
     Done(byteReadUint_32(file,&count));

+ 136 - 28
src/core/env.c

@@ -6,7 +6,8 @@ static bool checkInheritAPI(af_ObjectData *od);
 static void checkInherit(af_Inherit **ih, af_Object *obj);
 static bool enableCore(af_Core *core);
 
-static af_Activity *makeActivity(af_Code *bt, bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong);
+static af_Activity *makeActivity(af_Code *bt_top, af_Code *bt_start, bool return_first, af_Message *msg_up,
+                                 af_VarSpaceListNode *vsl, af_Object *belong, af_Object *func);
 static af_Activity *freeActivity(af_Activity *activity);
 static void freeAllActivity(af_Activity *activity);
 
@@ -23,7 +24,12 @@ static af_Core *makeCore(void) {
 }
 
 static void freeCore(af_Core *core) {
-    freeVarSpace(core->protect);  // 无论是否gc接管都释放
+    if (core->object != NULL)
+        gc_delReference(core->object);
+    if (core->global != NULL)
+        gc_delReference(core->global);
+    if (core->protect != NULL)
+        freeVarSpace(core->protect);  // 无论是否gc接管都释放
     gc_freeAllValue(core);
     free(core);
 }
@@ -111,30 +117,52 @@ static bool enableCore(af_Core *core) {
             return false;
     }
 
+    gc_addReference(object);
+    gc_addReference(global);
     core->in_init = false;
     return true;
 }
 
-static af_Activity *makeActivity(af_Code *bt, bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong) {
+static af_Activity *makeActivity(af_Code *bt_top, af_Code *bt_start, bool return_first, af_Message *msg_up,
+                                 af_VarSpaceListNode *vsl, af_Object *belong, af_Object *func) {
     af_Activity *activity = calloc(sizeof(af_Activity), 1);
-    activity->bt = bt;
-    activity->bt_start = bt;
-
-    if (new_vs) {
-        activity->var_list = pushNewVarList(vsl);
-        activity->new_vs_count = 1;
-    } else {
-        activity->var_list = vsl;
-        activity->new_vs_count = 0;
-    }
+    activity->status = act_func;
+
+    activity->msg_up = msg_up;
+    activity->msg_up_count = 0;
+
+    activity->var_list = vsl;
+    activity->new_vs_count = 0;
 
     activity->belong = belong;
+    activity->func = func;
+    gc_addReference(belong);
+    gc_addReference(func);
+
+    activity->bt_top = bt_top;
+    activity->bt_start = bt_start;
+    activity->bt_next = bt_start;
+
+    activity->return_first = return_first;
     return activity;
 }
 
 static af_Activity *freeActivity(af_Activity *activity) {
     af_Activity *prev = activity->prev;
     af_VarSpaceListNode *vs = activity->var_list;
+    af_Message *msg_up = activity->msg_up;
+
+    gc_delReference(activity->belong);
+    gc_delReference(activity->func);
+
+    if (activity->return_msg != NULL)
+        freeMessage(activity->return_msg);
+    freeAllMessage(activity->msg_down);  // msg转移后需要将对应成员设置为NULL
+    for (int i = activity->msg_up_count; i > 0; i--) {
+        if (msg_up == NULL)  // 发生了错误
+            break;
+        msg_up = freeMessage(msg_up);
+    }
 
     for (int i = activity->new_vs_count; i > 0; i--) {
         if (vs == NULL)  // 发生了错误
@@ -142,8 +170,6 @@ static af_Activity *freeActivity(af_Activity *activity) {
         vs = popLastVarList(vs);
     }
 
-    freeAllMessage(activity->msg_up);  // msg转移后需要将对应成员设置为NULL
-    freeAllMessage(activity->msg_down);
     free(activity);
     return prev;
 }
@@ -177,6 +203,7 @@ void freeAllMessage(af_Message *msg) {
 void pushMessageUp(af_Message *msg, af_Environment *env) {
     msg->next = env->activity->msg_up;
     env->activity->msg_up = msg;
+    env->activity->msg_up_count++;
 }
 
 void pushMessageDown(af_Message *msg, af_Environment *env) {
@@ -184,28 +211,40 @@ void pushMessageDown(af_Message *msg, af_Environment *env) {
     env->activity->msg_down = msg;
 }
 
-af_Message *popMessageUp(char *type, af_Environment *env) {
+void *popMessageUp(char *type, af_Environment *env) {
     for (af_Message **pmsg = &env->activity->msg_up; *pmsg != NULL; pmsg = &((*pmsg)->next)) {
-        if (EQ_STR((*pmsg)->type, type)) {
-            af_Message *msg = *pmsg;
-            *pmsg = msg->next;
-            return msg;
-        }
+        if (EQ_STR((*pmsg)->type, type))
+            return (*pmsg)->msg;  // msg_up是只读的
     }
     return NULL;
 }
 
+/*
+ * 函数名: getMessageData
+ * 目标: 获取`msg`的数据, 对外API
+ */
+void *getMessageData(af_Message *msg) {
+    return msg->msg;
+}
+
 af_Message *popMessageDown(char *type, af_Environment *env) {
     for (af_Message **pmsg = &env->activity->msg_down; *pmsg != NULL; pmsg = &((*pmsg)->next)) {
         if (EQ_STR((*pmsg)->type, type)) {
             af_Message *msg = *pmsg;
             *pmsg = msg->next;
+            msg->next = NULL;
             return msg;
         }
     }
     return NULL;
 }
 
+void connectMessage(af_Message **base, af_Message *msg) {
+    while (*base != NULL)
+        base = &((*base)->next);
+    *base = msg;
+}
+
 static af_EnvVar *makeEnvVar(char *name, char *data) {
     af_EnvVar *var = calloc(sizeof(af_EnvVar), 1);
     var->name = strCopy(name);
@@ -275,11 +314,11 @@ bool enableEnvironment(af_Code *bt, af_Environment *env) {
     if (!enableCore(env->core))
         return false;
 
-    env->activity = makeActivity(bt, false, NULL, env->core->global);
+    env->activity = makeActivity(NULL, bt, false, NULL, NULL, env->core->global, NULL);
     env->activity->new_vs_count = 2;
     env->activity->var_list = makeVarSpaceList(env->core->global->data->var_space);
     env->activity->var_list->next = makeVarSpaceList(env->core->protect);
-    env->activity->is_top = true;  // 设置为最顶层
+    env->activity->status = act_normal;
     return true;
 }
 
@@ -290,13 +329,82 @@ void freeEnvironment(af_Environment *env) {
     free(env);
 }
 
-void pushActivity(af_Code *bt, bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong,
-                  af_Environment *env) {
-    af_Activity *activity = makeActivity(bt, new_vs, vsl, belong);
+bool pushExecutionActivity(af_Code *bt, bool return_first, af_Environment *env) {
+    af_Code *next;
+    if (!getCodeBlockNext(bt, &next))
+        return false;
+
+    af_Activity *activity = makeActivity(bt, bt->next, return_first, env->activity->msg_up,
+                                         env->activity->var_list, env->activity->belong,
+                                         env->activity->func);
+    env->activity->bt_next = next;
+    activity->prev = env->activity;
+    env->activity = activity;
+    env->activity->status = act_normal;
+    return true;
+}
+
+bool pushFuncActivity(af_Code *bt, af_Environment *env) {
+    af_Code *next;
+    if (!getCodeBlockNext(bt, &next))
+        return false;
+
+    af_Activity *activity = makeActivity(bt, bt->next, false, env->activity->msg_up,
+                                         env->activity->var_list, env->activity->belong,
+                                         env->activity->func);
+    env->activity->bt_next = next;
     activity->prev = env->activity;
     env->activity = activity;
+    env->activity->status = act_func;
+    return true;
+}
+
+bool setFuncActivityToArg(af_Object *func, af_Environment *env) {
+    gc_delReference(env->activity->belong);
+    gc_delReference(env->activity->func);
+    gc_addReference(func);
+    gc_addReference(func->belong);
+
+    env->activity->func = func;
+    env->activity->belong = func->belong;
+    env->activity->status = act_arg;
+    // TODO-szh 参数处理(计算)
+    return true;
 }
 
-void popActivity(af_Environment *env) {
-    env->activity = freeActivity(env->activity);
+bool setFuncActivityAddVar(af_VarSpaceListNode *vsl, bool new_vsl, bool is_protect, char **msg_type, af_Environment *env) {
+    if (env->activity->new_vs_count != 0 || !new_vsl && is_protect)
+        return false;
+
+    if (vsl != NULL)
+        env->activity->var_list = vsl;
+    if (new_vsl) {
+        env->activity->var_list = pushNewVarList(env->activity->var_list);
+        env->activity->new_vs_count = 1;
+    }
+
+    env->activity->msg_type = msg_type;
+    // TODO-szh 参数处理(赋值)
+    env->activity->var_list->vs->is_protect = is_protect;
+    return true;
+}
+
+bool setFuncActivityToNormal(af_Code *bt, af_Environment *env) {
+    env->activity->bt_start = bt;
+    env->activity->bt_next = bt;
+    env->activity->status = act_normal;
+    return true;
+}
+
+void popActivity(af_Message *msg, af_Environment *env) {
+    if (env->activity->prev != NULL && msg != NULL) {
+        af_Message *new_msg = msg;
+        msg->next = env->activity->prev->msg_down;
+        env->activity->prev->msg_down = msg;
+        if (env->activity->msg_down != NULL) {
+            connectMessage(&new_msg, env->activity->msg_down);
+            env->activity->msg_down = NULL;
+        }
+    }
+    env->activity = freeActivity(env->activity);  // TODO-szh activity需要添加gc
 }

+ 3 - 0
src/core/var.c

@@ -151,6 +151,9 @@ bool addVarToVarSpace(af_Var *var, af_VarSpace *vs) {
     time33_t index = time33(var->name);
     af_VarCup **pCup = &vs->var[index];
 
+    if (vs->is_protect == true)
+        return false;
+
     for (NULL; *pCup != NULL; pCup = &((*pCup)->next)) {
         if (EQ_STR((*pCup)->var->name, var->name))
             return false;