2
0
Эх сурвалжийг харах

feat: 添加了gc模块及其依赖模块的头文件

添加了gc模块
添加了gc模块所依赖模块的头文件
SongZihuan 3 жил өмнө
parent
commit
57b958308d

+ 7 - 3
include/aFun.h

@@ -1,12 +1,16 @@
-#ifndef AFUN__H
-#define AFUN__H
+#ifndef AFUN__AFUN_H
+#define AFUN__AFUN_H
 #include "mem.h"
 #include "macro.h"
 #include "tool.h"
 
 #include "bytecode.h"
+#include "object.h"
+#include "var.h"
+#include "env.h"
+#include "gc.h"
 
 // Init系列函数
 void aFunInit(void);
 
-#endif //AFUN__H
+#endif //AFUN__AFUN_H

+ 3 - 4
include/bytecode.h

@@ -1,6 +1,5 @@
-#ifndef AFUN_BYTECODE_H
-#define AFUN_BYTECODE_H
-// 相关结构体的定义
+#ifndef AFUN__BYTECODE_H_PUBLIC
+#define AFUN__BYTECODE_H_PUBLIC
 typedef struct af_ByteCode af_ByteCode;
 
 enum af_BlockType {
@@ -21,4 +20,4 @@ bool writeAllByteCode(af_ByteCode *bt, FILE *file);
 bool readAllByteCode(af_ByteCode **bt, FILE *file);
 void printByteCode(af_ByteCode *bt);
 
-#endif //AFUN_BYTECODE_H
+#endif //AFUN__BYTECODE_H_PUBLIC

+ 3 - 3
include/cjson.h

@@ -1,8 +1,8 @@
-#ifndef CJSON__H
-#define CJSON__H
+#ifndef AFUN__CJSON_H
+#define AFUN__CJSON_H
 #include "macro.h"
 #include "cJSON/cJSON.h"
 void cJsonInit();
 cJSON *parseJsonFile(FILE *file);
 
-#endif // CJSON__H
+#endif // AFUN__CJSON_H

+ 8 - 0
include/env.h

@@ -0,0 +1,8 @@
+#ifndef AFUN__ENV_H_PUBLIV
+#define AFUN__ENV_H_PUBLIV
+
+typedef struct af_Core af_Core;
+typedef struct af_Activity af_Activity;
+typedef struct af_Environment af_Environment;
+
+#endif //AFUN__ENV_H_PUBLIV

+ 13 - 0
include/gc.h

@@ -0,0 +1,13 @@
+#ifndef AFUN__GC_H_PUBLIC
+#define AFUN__GC_H_PUBLIC
+#include "object.h"
+#include "var.h"
+
+void gc_addObjectData(af_ObjectData *obj, af_Core *core);
+void gc_addObject(af_Object *obj, af_Core *core);
+void gc_addVar(af_Var *obj, af_Core *core);
+void gc_addVarSpace(af_VarSpace *obj, af_Core *core);
+
+bool resetGC(af_Core *core);
+
+#endif //AFUN__GC_H_PUBLIC

+ 3 - 3
include/macro.h

@@ -3,8 +3,8 @@
  * 目标: 定义公共宏 和 公共头文件
  */
 
-#ifndef MACRO__H
-#define MACRO__H
+#ifndef AFUN__MACRO_H
+#define AFUN__MACRO_H
 #include <stdbool.h>
 #include <inttypes.h>
 #include "mem.h"
@@ -23,4 +23,4 @@ typedef char *FilePath;  // 文件路径
 
 typedef unsigned int ByteCodeUint;  // ByteCode int
 
-#endif //MACRO__H
+#endif //AFUN__MACRO_H

+ 3 - 3
include/mem.h

@@ -3,8 +3,8 @@
  * 目标: 内存管理工具的头文件
  */
 
-#ifndef MEM__H
-#define MEM__H
+#ifndef AFUN__MEM_H
+#define AFUN__MEM_H
 
 #include <stdlib.h>
 #define free(p) ((((p)!=NULL) ? (free(p), NULL) : NULL), (p)=NULL)  // free不是可选的宏
@@ -22,4 +22,4 @@ static void *safeCalloc(size_t n, size_t size) {
 #define calloc(n, size) (safeCalloc(n, size))
 
 #endif
-#endif  // MEM__H
+#endif  // AFUN__MEM_H

+ 7 - 0
include/object.h

@@ -0,0 +1,7 @@
+#ifndef AFUN__OBJECT_H_PUBLIC
+#define AFUN__OBJECT_H_PUBLIC
+
+typedef struct af_Object af_Object;
+typedef struct af_ObjectData af_ObjectData;
+
+#endif //AFUN__OBJECT_H_PUBLIC

+ 3 - 3
include/tool.h

@@ -4,8 +4,8 @@
  * aFunTool是aFun实用工具库, 内含aFun调用的实用函数
  */
 
-#ifndef TOOL__H
-#define TOOL__H
+#ifndef AFUN__TOOL_H
+#define AFUN__TOOL_H
 #include <wchar.h>
 #include <string.h>
 #include <signal.h>
@@ -155,4 +155,4 @@ bool byteReadUint_16(FILE *file, uint16_t *num);
 bool byteReadUint_32(FILE *file, uint32_t *num);
 bool byteReadUint_64(FILE *file, uint64_t *num);
 bool byteReadStr(FILE *file, char **str);
-#endif //TOOL__H
+#endif //AFUN__TOOL_H

+ 8 - 0
include/var.h

@@ -0,0 +1,8 @@
+#ifndef AFUN__VAR_H_PUBLIC
+#define AFUN__VAR_H_PUBLIC
+#include "macro.h"
+
+typedef struct af_Var af_Var;
+typedef struct af_VarSpace af_VarSpace;
+
+#endif //AFUN__VAR_H_PUBLIC

+ 4 - 4
src/core/__bytecode.h

@@ -1,10 +1,10 @@
 /*
- * 文件名: bytecode.h
+ * 文件名: __bytecode.h
  * 目标: 定义ByteCode结构体
  */
 
-#ifndef BYTECODE__H
-#define BYTECODE__H
+#ifndef AFUN__BYTECODE_H
+#define AFUN__BYTECODE_H
 #include "macro.h"
 #include "bytecode.h"
 
@@ -40,4 +40,4 @@ struct af_ByteCode {  // 一个 ByteCode 的结构体
     struct af_ByteCode *next;
 };
 
-#endif //BYTECODE__H
+#endif //AFUN__BYTECODE_H

+ 41 - 0
src/core/__env.h

@@ -0,0 +1,41 @@
+#ifndef AFUN__ENV_H
+#define AFUN__ENV_H
+#include "macro.h"
+#include "__object.h"
+#include "__var.h"
+#include "__bytecode.h"
+#include "env.h"
+#include "__gc.h"
+
+struct af_Core {  // 解释器核心
+    // GC基本信息
+    af_ObjectData(*gc_ObjectData);
+    af_Object(*gc_Object);
+    af_Var(*gc_Var);
+    af_VarSpace(*gc_VarSpace);
+
+    // 基本量信息
+    struct af_Object *global;  // 顶级属对象
+    struct af_Object *belong;  // 顶级继承对象
+
+    // 保护空间
+    bool in_init;  // 是否在初始化模式
+    struct af_VarSpace *protect;  // 顶级保护变量空间
+};
+
+struct af_Activity {  // 活动记录器
+    struct af_Activity *prev;  // 上一个活动记录器
+
+    struct af_ByteCode *bt_start;  // 代码的起始位置
+    struct af_ByteCode *bt;  // 指示代码运行的地方
+
+    struct af_VarSpaceListNode *var_list;  // 变量空间
+    bool var_free;  // 是否需要释放变量空间
+};
+
+struct af_Environment {  // 运行环境
+    struct af_Core *core;
+    struct af_Activity *activity;
+};
+
+#endif //AFUN__ENV_H

+ 46 - 0
src/core/__gc.h

@@ -0,0 +1,46 @@
+#ifndef AFUN_GC_H
+#define AFUN_GC_H
+#include "macro.h"
+#include "env.h"
+#include "gc.h"
+
+#define GC_CHAIN(type) struct type *next, *prev;
+typedef uint32_t GcCount;
+
+struct gc_info {
+    bool start_gc;  // 启用gc
+    bool not_clear;  // 不清除
+    GcCount *reference;  // 引用计数
+    bool reachable;  // 可达标记 [同时标识已迭代]
+};
+
+typedef struct GC_ObjectData GC_ObjectData;
+struct GC_ObjectData {
+    struct gc_info info;
+    GC_CHAIN(af_ObjectData);
+    bool done_del;  // 是否已析构
+};
+
+typedef struct GC_Object GC_Object;
+struct GC_Object {
+    struct gc_info info;
+    GC_CHAIN(af_Object);
+};
+
+typedef struct GC_Var GC_Var;
+struct GC_Var {
+    struct gc_info info;
+    GC_CHAIN(af_Var);
+};
+
+typedef struct GC_VarSpace GC_VarSpace;
+struct GC_VarSpace {
+    struct gc_info info;
+    GC_CHAIN(af_VarSpace);
+};
+
+#undef GC_CHAIN
+
+bool gc_RunGC(af_Environment *env);
+
+#endif //AFUN_GC_H

+ 61 - 0
src/core/__object.h

@@ -0,0 +1,61 @@
+/*
+ * 文件名: __object.h
+ * 目标: 定义aft对象的结构体
+ */
+
+#ifndef AFUN__OBJECT_H
+#define AFUN__OBJECT_H
+#include "macro.h"
+#include "tool.h"
+#include "object.h"
+#include "__gc.h"
+
+#define API_HASHTABLE_SIZE (8)
+
+typedef struct af_Inherit af_Inherit;
+typedef struct af_ObjectAPINode af_ObjectAPINode;
+typedef struct af_ObjectAPI af_ObjectAPI;
+
+typedef void pValueAPI();
+NEW_DLC_SYMBOL(pValueAPI, pAPIFUNC);
+
+struct af_ObjectAPINode {
+    char *api_name;  // api名字
+    DLC_SYMBOL(pAPIFUNC) api;  // api函数
+    struct af_ObjectAPINode *next;
+};
+
+struct af_ObjectAPI {
+    uint32_t count;  // api个数记录
+    struct af_ObjectAPINode (*node)[API_HASHTABLE_SIZE];
+};
+
+struct af_ObjectData {
+    char *id;  // 对象类型标识符(一个字符串)
+
+    void *data;
+    size_t size;  // 标记data的大小
+
+    struct af_ObjectAPI *api;  // 继承的api必须位于Inherit链中
+    bool allow_inherit;  // 是否允许被继承
+    bool inherit_api;  // api被继承
+
+    struct af_VarSpace *var_space;
+    struct af_Inherit *iherit;  // 只有顶级继承对象的iherit属性可为NULL
+
+    struct af_Object *base;  // 在gc机制中, 当对想要被释放前, 调用析构函数是对象以该base的身份出现
+    GC_ObjectData gc;
+};
+
+struct af_Object {
+    struct af_Object *belong;  // 只有顶级属对象的belong属性可为NULL
+    struct af_ObjectData *data;
+    GC_Object gc;
+};
+
+struct af_Inherit {
+    struct af_Object *obj;
+    struct af_Inherit *next;
+};
+
+#endif //AFUN__OBJECT_H

+ 42 - 0
src/core/__var.h

@@ -0,0 +1,42 @@
+#ifndef AFUN__VAR_H
+#define AFUN__VAR_H
+#include "macro.h"
+#include "var.h"
+#include "__gc.h"
+
+#define VAR_HASHTABLE_SIZE (8)
+
+typedef struct af_VarNode af_VarNode;
+typedef struct af_VarSpaceListNode af_VarSpaceListNode;
+typedef struct af_VarCup af_VarCup;
+
+struct af_VarNode {
+    char *id;  // 变量存储值的id为NULL
+    char permissions[3];  // 读-1 写-2 读且写-3 不读不写-0 [自己权限 后代权限 外部权限]
+    struct af_Object *obj;
+    struct af_VarNode *next;
+};
+
+struct af_Var {
+    char *name;
+    struct af_VarNode *vn;
+    GC_Var gc;
+};
+
+struct af_VarCup {
+    struct af_Var *var;
+    struct af_VarCup *next;
+};
+
+struct af_VarSpace {
+    bool is_protect;  // 是否为保护变量空间
+    struct af_VarCup (*var)[VAR_HASHTABLE_SIZE];
+    GC_VarSpace gc;
+};
+
+struct af_VarSpaceListNode {  // 变量链
+    struct af_VarSpace *vs;
+    struct af_VarSpaceListNode *next;
+};
+
+#endif //AFUN__VAR_H

+ 299 - 0
src/core/gc.c

@@ -0,0 +1,299 @@
+#include "aFun.h"
+#include "__object.h"
+#include "__var.h"
+#include "__gc.h"
+#include "__env.h"
+
+typedef struct gc_Analyzed gc_Analyzed;
+typedef struct 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 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 reachableObjectData(struct af_ObjectData *od, pgc_Analyzed plist);
+static pgc_Analyzed reachableObject(struct af_Object *od, pgc_Analyzed plist);
+
+static void freeValue(af_Core *core);
+static pgc_Analyzed reachable(af_Activity *active, 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;
+}
+
+static gc_Analyzed *freeAnalyzed(gc_Analyzed *base) {
+    gc_Analyzed *next = base->next;
+    free(base);
+    return next;
+}
+
+static void freeAllAnalyzed(gc_Analyzed *base) {
+    while (base != NULL)
+        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;
+
+    *plist = makeAnalyzed(gc_VarSpace, vs);
+    return &((*plist)->next);
+}
+
+// 使用 gc_Analyzed 目的是令可达性分析程序不需要使用递归
+// Object->OvjectData->VarSpace->Var; 仅允许单项调用, 不发生递归
+
+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;
+        if (!od->data->gc.info.reachable)
+            plist = reachableObjectData(od->data, plist);
+    }
+    return plist;
+}
+
+static pgc_Analyzed reachableObjectData(struct af_ObjectData *od, pgc_Analyzed plist) {  // 暂时不考虑API调用
+    if (od->gc.info.reachable)
+        return plist;
+
+    od->gc.info.reachable = true;
+    plist = reachableVarSpace(od->var_space, plist);
+
+    if (!od->base->gc.info.reachable)
+        plist = newObjectAnalyzed(od->base, plist);
+
+    for (af_Inherit *ih = od->iherit; ih != NULL; ih = ih->next) {
+        if (!ih->obj->gc.info.reachable)
+            plist = newObjectAnalyzed(ih->obj, plist);
+    }
+
+    return plist;
+}
+
+static pgc_Analyzed reachableVarSpace(struct af_VarSpace *vs, pgc_Analyzed plist) {
+    if (vs->gc.info.reachable)
+        return plist;
+
+    vs->gc.info.reachable = true;
+    for (int i = 0; i < VAR_HASHTABLE_SIZE; i++) {
+        for (af_VarCup *var = vs->var[i]; var != NULL; var = var->next)
+            plist = reachableVar(var->var, plist);
+    }
+
+    return plist;
+}
+
+static pgc_Analyzed reachableVar(struct af_Var *var, pgc_Analyzed plist) {
+    if (var->gc.info.reachable)
+        return 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);
+    }
+
+    return plist;
+}
+
+static pgc_Analyzed iterLinker(af_Core *core, pgc_Analyzed plist) {
+    plist = reachableVarSpace(core->protect, plist);
+    plist = reachableObject(core->belong, plist);
+    plist = reachableObject(core->global, plist);
+
+    for (af_ObjectData *od = core->gc_ObjectData; od != NULL; od = od->gc.next) {
+        if (!od->gc.info.reachable && (od->gc.info.reference > 0 || od->gc.info.not_clear))
+            plist = reachableObjectData(od, plist);
+    }
+
+    for (af_Object *obj = core->gc_Object; obj != NULL; obj = obj->gc.next) {
+        if (!obj->gc.info.reachable && (obj->gc.info.reference > 0 || obj->gc.info.not_clear))
+            plist = reachableObject(obj, plist);
+    }
+
+    for (af_VarSpace *vs = core->gc_VarSpace; vs != NULL; vs = vs->gc.next) {
+        if (!vs->gc.info.reachable && (vs->gc.info.reference > 0 || vs->gc.info.not_clear))
+            plist = reachableVarSpace(vs, plist);
+    }
+
+    for (af_Var *var = core->gc_Var; var != NULL; var = var->gc.next) {
+        if (!var->gc.info.reachable && (var->gc.info.reference > 0 || var->gc.info.not_clear))
+            plist = reachableVar(var, plist);
+    }
+    return plist;
+}
+
+static pgc_Analyzed reachable(af_Activity *active, pgc_Analyzed plist) {
+    for (NULL; active != NULL; active = active->prev) {
+        for (af_VarSpaceListNode *vsn = active->var_list; vsn != NULL; vsn = vsn->next) {
+            if (!vsn->vs->gc.info.reachable)
+                plist = reachableVarSpace(vsn->vs, plist);
+        }
+    }
+    return plist;
+}
+
+bool resetGC(af_Core *core) {
+    for (af_ObjectData *od = core->gc_ObjectData; od != NULL; od = od->gc.next)
+        od->gc.info.reachable = false;
+
+    for (af_Object *obj = core->gc_Object; obj != NULL; obj = obj->gc.next)
+        obj->gc.info.reachable = false;
+
+    for (af_VarSpace *vs = core->gc_VarSpace; vs != NULL; vs = vs->gc.next) {
+        vs->gc.info.reachable = false;
+        if (!vs->gc.info.start_gc)  // 未启用gc但却在gc链中
+            return false;
+    }
+
+    for (af_Var *var = core->gc_Var; var != NULL; var = var->gc.next) {
+        var->gc.info.reachable = false;
+        if (!var->gc.info.start_gc)  // 未启用gc但却在gc链中
+            return false;
+    }
+
+    return true;
+}
+
+#define FREE_EXCHANGE(obj) do { \
+if ((obj)->gc.prev != NULL) (obj)->gc.prev->gc.next = (obj)->gc.next; \
+if ((obj)->gc.next != NULL) (obj)->gc.next->gc.prev = (obj)->gc.prev; } while(0)
+
+static void freeValue(af_Core *core) {
+    for (af_ObjectData *od = core->gc_ObjectData, *next; od != NULL; od = next) {
+        next = od->gc.next;
+        if (!od->gc.info.reachable) {  // 暂时不考虑析构函数
+            FREE_EXCHANGE(od);
+            // 释放函数
+        }
+    }
+
+    for (af_Object *obj = core->gc_Object, *next; obj != NULL; obj = next) {
+        next = obj->gc.next;
+        if (!obj->gc.info.reachable) {
+            FREE_EXCHANGE(obj);
+            // 释放函数
+        }
+    }
+
+    for (af_VarSpace *vs = core->gc_VarSpace, *next; vs != NULL; vs = next) {
+        next = vs->gc.next;
+        if (!vs->gc.info.reachable) {
+            FREE_EXCHANGE(vs);
+            // 释放函数
+        }
+    }
+
+    for (af_Var *var = core->gc_Var, *next; var != NULL; var = next) {
+        next = var->gc.next;
+        if (!var->gc.info.reachable) {
+            FREE_EXCHANGE(var);
+            // 释放函数
+        }
+    }
+}
+
+#undef FREE_EXCHANGE
+
+#define GC_ADD_FUNC_DEFINED(type) \
+void gc_add##type(af_##type *obj, af_Core *core) { \
+    obj->gc.prev = NULL; \
+    obj->gc.next = core->gc_##type; \
+    core->gc_##type = obj; \
+}
+
+GC_ADD_FUNC_DEFINED(ObjectData)
+GC_ADD_FUNC_DEFINED(Object)
+GC_ADD_FUNC_DEFINED(Var)
+GC_ADD_FUNC_DEFINED(VarSpace)
+
+#undef GC_ADD_FUNC_DEFINED
+
+bool gc_RunGC(af_Environment *env) {
+    gc_Analyzed *analyzed;
+    pgc_Analyzed plist = &analyzed;
+
+    if (!resetGC(env->core))
+        return false;
+
+    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;
+        }
+    }
+
+    freeValue(env->core);
+    freeAllAnalyzed(analyzed);
+    return true;
+}
+