Selaa lähdekoodia

feat: 添加env模块

SongZihuan 3 vuotta sitten
vanhempi
sitoutus
e70919d6a2
13 muutettua tiedostoa jossa 309 lisäystä ja 45 poistoa
  1. 2 0
      include/bytecode.h
  2. 13 2
      include/env.h
  3. 4 4
      include/gc.h
  4. 4 3
      include/object.h
  5. 8 4
      include/var.h
  6. 17 8
      src/core/__env.h
  7. 10 3
      src/core/__gc.h
  8. 2 2
      src/core/__object.h
  9. 3 1
      src/core/__var.h
  10. 176 0
      src/core/env.c
  11. 35 10
      src/core/gc.c
  12. 4 4
      src/core/object.c
  13. 31 4
      src/core/var.c

+ 2 - 0
include/bytecode.h

@@ -1,5 +1,7 @@
 #ifndef AFUN__BYTECODE_H_PUBLIC
 #define AFUN__BYTECODE_H_PUBLIC
+#include <stdio.h>
+
 typedef struct af_ByteCode af_ByteCode;
 
 enum af_BlockType {

+ 13 - 2
include/env.h

@@ -1,8 +1,19 @@
 #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;
 
+#include "bytecode.h"
+#include "object.h"
+#include "var.h"
+
+af_Object *getBaseObject(char *name, af_Environment *env);
+
+af_Environment *makeEnvironment(void);
+bool enableEnvironment(af_ByteCode *bt, af_Environment *env);
+void freeEnvironment(af_Environment *env);
+void pushActivity(af_ByteCode *bt, bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong,
+                  af_Environment *env);
+void popActivity(af_Environment *env);
+
 #endif //AFUN__ENV_H_PUBLIV

+ 4 - 4
include/gc.h

@@ -3,10 +3,10 @@
 #include "object.h"
 #include "var.h"
 
-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);
+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);
 
-bool resetGC(af_Core *core);
+bool resetGC(af_Environment *env);
 
 #endif //AFUN__GC_H_PUBLIC

+ 4 - 3
include/object.h

@@ -1,16 +1,17 @@
 #ifndef AFUN__OBJECT_H_PUBLIC
 #define AFUN__OBJECT_H_PUBLIC
-#include "env.h"
-#include "tool.h"
 
 typedef struct af_Object af_Object;
 typedef struct af_Inherit af_Inherit;
 
+#include "env.h"
+#include "tool.h"
+
 af_Object *makeObject(char *id, size_t data_size, bool inherit_api, bool allow_iherit,
                       af_Inherit *inherit, af_Environment *env);
 void freeObject(af_Object *obj);
 
-af_Inherit *makenIherit(af_Object *obj);
+af_Inherit *makeIherit(af_Object *obj);
 af_Inherit *freeIherit(af_Inherit *ih);
 void freeAllIherit(af_Inherit *ih);
 

+ 8 - 4
include/var.h

@@ -1,12 +1,13 @@
 #ifndef AFUN__VAR_H_PUBLIC
 #define AFUN__VAR_H_PUBLIC
-#include "macro.h"
-#include "object.h"
 
 typedef struct af_Var af_Var;
 typedef struct af_VarSpace af_VarSpace;
 typedef struct af_VarSpaceListNode af_VarSpaceListNode;
 
+#include "macro.h"
+#include "object.h"
+
 af_Var *makeVar(char *name, char p_self, char p_posterity, char p_external, af_Object *obj);
 void freeVar(af_Var *var);
 void addVarNode(af_Var var, af_Object *obj, char *id);
@@ -18,8 +19,8 @@ af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs);
 af_VarSpaceListNode *freeVarSpaceList(af_VarSpaceListNode *vsl);
 void freeAllVarSpaceList(af_VarSpaceListNode *vsl);
 
-void addVarSpaceGC(af_VarSpace *vs, af_Core *core);
-void addVarGC(af_Var *var, af_Core *core);
+void addVarSpaceGC(af_VarSpace *vs, af_Environment *env);
+void addVarGC(af_Var *var, af_Environment *env);
 
 bool addVarToVarSpace(af_Var *var, af_VarSpace *vs);
 bool makeVarToVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj,
@@ -28,4 +29,7 @@ bool makeVarToVarSpace(char *name, char p_self, char p_posterity, char p_externa
 af_Var *findVarFromVarSpace(char *name, af_VarSpace *vs);
 af_Var *findVarFromVarList(char *name, af_VarSpaceListNode *vsl);
 
+af_VarSpaceListNode *pushNewVarList(af_VarSpaceListNode *base);
+af_VarSpaceListNode *popLastVarList(af_VarSpaceListNode *base);
+
 #endif //AFUN__VAR_H_PUBLIC

+ 17 - 8
src/core/__env.h

@@ -1,20 +1,27 @@
 #ifndef AFUN__ENV_H
 #define AFUN__ENV_H
 #include "macro.h"
+
+typedef struct af_Core af_Core;
+typedef struct af_Activity af_Activity;
+
+#include "env.h"
 #include "__object.h"
 #include "__var.h"
 #include "__bytecode.h"
-#include "env.h"
 #include "__gc.h"
 
+
+typedef uint16_t ActivityCount;
+
 struct af_Core {  // 解释器核心
     // GC基本信息
-    af_ObjectData(*gc_ObjectData);
-    af_Object(*gc_Object);
-    af_Var(*gc_Var);
-    af_VarSpace(*gc_VarSpace);
+    struct af_ObjectData *gc_ObjectData;
+    struct af_Object *gc_Object;
+    struct af_Var *gc_Var;
+    struct af_VarSpace *gc_VarSpace;
 
-    // 基本信息
+    // 基本对象信息
     struct af_Object *global;  // 顶级属对象
     struct af_Object *object;  // 顶级继承对象
 
@@ -30,9 +37,9 @@ struct af_Activity {  // 活动记录器
     struct af_ByteCode *bt;  // 指示代码运行的地方
 
     struct af_VarSpaceListNode *var_list;  // 变量空间
-    bool var_free;  // 是否需要释放变量空间
+    ActivityCount new_vs_count;  // 需要释放的空间数
 
-    af_Object *belong;  // 属对象
+    struct af_Object *belong;  // 属对象
 };
 
 struct af_Environment {  // 运行环境
@@ -40,4 +47,6 @@ struct af_Environment {  // 运行环境
     struct af_Activity *activity;
 };
 
+af_Object *getBaseObjectFromCore(char *name, af_Core *core);
+
 #endif //AFUN__ENV_H

+ 10 - 3
src/core/__gc.h

@@ -1,8 +1,6 @@
 #ifndef AFUN_GC_H
 #define AFUN_GC_H
 #include "macro.h"
-#include "env.h"
-#include "gc.h"
 
 typedef struct GC_Var GC_Var;
 typedef struct GC_VarSpace GC_VarSpace;
@@ -47,7 +45,16 @@ struct GC_VarSpace {
 
 #undef GC_CHAIN
 
+#include "__env.h"  // 这部分内容依赖上面的定义
+#include "gc.h"
+
+void gc_addObjectData(struct af_ObjectData *obj, af_Environment *env);  // af_ObjectData 不对外公开
+void gc_addObjectDataByCore(struct af_ObjectData *obj, af_Core *core);
+void gc_addObjectByCore(struct af_Object *obj, af_Core *core);
+void gc_addVarByCore(struct af_Var *obj, af_Core *core);
+void gc_addVarSpaceByCore(struct af_VarSpace *obj, af_Core *core);
+
 bool gc_RunGC(af_Environment *env);
-void gc_addObjectData(struct af_ObjectData *obj, af_Core *core);  // af_ObjectData 不对外公开
+void gc_freeAllValue(af_Core *core);
 
 #endif //AFUN_GC_H

+ 2 - 2
src/core/__object.h

@@ -5,14 +5,14 @@
 
 #ifndef AFUN__OBJECT_H
 #define AFUN__OBJECT_H
+#include "macro.h"
+#include "tool.h"
 
 // 这些typedef可能会被下面include的文件使用
 typedef struct af_ObjectData af_ObjectData;
 typedef struct af_ObjectAPINode af_ObjectAPINode;
 typedef struct af_ObjectAPI af_ObjectAPI;
 
-#include "macro.h"
-#include "tool.h"
 #include "object.h"
 #include "__gc.h"
 

+ 3 - 1
src/core/__var.h

@@ -1,11 +1,11 @@
 #ifndef AFUN__VAR_H
 #define AFUN__VAR_H
+#include "macro.h"
 
 // 这些typedef可能会被下面include的文件使用
 typedef struct af_VarNode af_VarNode;
 typedef struct af_VarCup af_VarCup;
 
-#include "macro.h"
 #include "var.h"
 #include "__gc.h"
 
@@ -40,5 +40,7 @@ struct af_VarSpaceListNode {  // 变量链
     struct af_VarSpaceListNode *next;
 };
 
+void addVarSpaceGCByCore(af_VarSpace *vs, af_Core *core);
+void addVarGCByCore(af_Var *var, af_Core *core);
 
 #endif //AFUN__VAR_H

+ 176 - 0
src/core/env.c

@@ -0,0 +1,176 @@
+#include "__env.h"
+
+static af_Core *makeCore(void);
+static void freeCore(af_Core *core);
+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_ByteCode *bt,bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong);
+static af_Activity *freeActivity(af_Activity *activity);
+static void freeAllActivity(af_Activity *activity);
+
+static af_Core *makeCore(void) {
+    af_Core *core = calloc(sizeof(af_Core), 1);
+    core->in_init = true;
+    core->protect = makeVarSpace();
+    return core;
+}
+
+static void freeCore(af_Core *core) {
+    freeVarSpace(core->protect);  // 无论是否gc接管都释放
+    gc_freeAllValue(core);
+    free(core);
+}
+
+/*
+ * 函数名: getBaseObjectFromCore
+ * 目标: 从VarSpace中获取一个量
+ * 作用: 用于init初始化时在保护空间获得一些初始化对象
+ */
+af_Object *getBaseObjectFromCore(char *name, af_Core *core) {
+    af_Var *var = findVarFromVarSpace(name, core->protect);
+    if (var != NULL)
+        return var->vn->obj;
+    return NULL;
+}
+
+/*
+ * 函数名: getBaseObject
+ * 目标: getBaseObjectFromCore的对外接口
+ */
+af_Object *getBaseObject(char *name, af_Environment *env) {
+    return getBaseObjectFromCore(name, env->core);
+}
+
+static void checkInherit(af_Inherit **ih, af_Object *obj) {
+    while (*ih != NULL) {
+        if ((*ih)->obj->data == obj->data) {
+            if ((*ih)->next == NULL && (*ih)->obj == obj)  // 最后一个就是obj
+                return;  // 不需要任何更改
+            *ih = freeIherit(*ih);  // 释放该ih
+        } else
+            ih = &((*ih)->next);
+    }
+    *ih = makeIherit(obj);
+}
+
+static bool checkInheritAPI(af_ObjectData *od) {
+    if (od->api != NULL)
+        return true;
+
+    if (!od->inherit_api)
+        return false;
+
+    if (od->iherit->obj->data->api == NULL && !checkInheritAPI(od->iherit->obj->data))
+        return false;
+
+    od->api = od->iherit->obj->data->api;
+    return true;
+}
+
+static bool enableCore(af_Core *core) {
+    af_Object *object = getBaseObjectFromCore("object", core);
+    af_Object *global = getBaseObjectFromCore("global", core);
+
+    if (global == NULL || global->belong != NULL)
+        return false;  // global未找到 或其有属对象
+
+    if (object == NULL || object->data->iherit != NULL || object->data->inherit_api || !object->data->allow_inherit)
+        return false;  // object未找到 或其继承自其他对象 或其使用继承api 或其不可被继承
+
+    core->global = global;
+    core->object = object;
+    addVarSpaceGCByCore(global->data->var_space, core);
+
+    for (af_Object *obj = core->object; obj != NULL; obj = obj->gc.next) {
+        if (obj == global)
+            continue;
+        if (obj->belong == NULL)
+            obj->belong = global;
+    }
+
+    af_ObjectData *last = NULL;
+    for (af_ObjectData *od = core->gc_ObjectData; od != NULL; od = od->gc.next) {
+        last = od;
+        if (od == object->data)
+            continue;
+        checkInherit(&od->iherit, object);
+    }
+
+    // 先创造的obj在后面, 因此倒着遍历, 先遍历到的obj依赖少, 可以减少checkInheritAPI递归的深度
+    for (af_ObjectData *od = last; od != NULL; od = od->gc.prev) {
+        if (od == object->data)
+            continue;
+        if(!checkInheritAPI(od))
+            return false;
+    }
+
+    core->in_init = false;
+    return true;
+}
+
+static af_Activity *makeActivity(af_ByteCode *bt, bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong) {
+    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->belong = belong;
+    return activity;
+}
+
+static af_Activity *freeActivity(af_Activity *activity) {
+    af_Activity *prev = activity->prev;
+    af_VarSpaceListNode *vs = activity->var_list;
+    for (int i = activity->new_vs_count; i > 0; i--) {
+        if (vs == NULL)  // 发生了错误
+            break;
+        vs = popLastVarList(vs);
+    }
+    free(activity);
+    return prev;
+}
+
+static void freeAllActivity(af_Activity *activity) {
+    while (activity != NULL)
+        activity = freeActivity(activity);
+}
+
+af_Environment *makeEnvironment(void) {
+    af_Environment *env = calloc(sizeof(af_Environment), 1);
+    env->core = makeCore();
+    return env;
+}
+
+bool enableEnvironment(af_ByteCode *bt, af_Environment *env) {
+    if (!enableCore(env->core))
+        return false;
+
+    env->activity = makeActivity(bt, false, NULL, env->core->global);
+    return true;
+}
+
+void freeEnvironment(af_Environment *env) {
+    freeCore(env->core);
+    freeAllActivity(env->activity);
+    free(env);
+}
+
+void pushActivity(af_ByteCode *bt, bool new_vs, af_VarSpaceListNode *vsl, af_Object *belong,
+                 af_Environment *env) {
+    af_Activity *activity = makeActivity(bt, new_vs, vsl, belong);
+    activity->prev = env->activity;
+    env->activity = activity;
+}
+
+void popActivity(af_Environment *env) {
+    env->activity = freeActivity(env->activity);
+}

+ 35 - 10
src/core/gc.c

@@ -187,20 +187,20 @@ static pgc_Analyzed reachable(af_Activity *active, pgc_Analyzed plist) {
     return plist;
 }
 
-bool resetGC(af_Core *core) {
-    for (af_ObjectData *od = core->gc_ObjectData; od != NULL; od = od->gc.next)
+bool resetGC(af_Environment *env) {
+    for (af_ObjectData *od = env->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)
+    for (af_Object *obj = env->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) {
+    for (af_VarSpace *vs = env->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) {
+    for (af_Var *var = env->core->gc_Var; var != NULL; var = var->gc.next) {
         var->gc.info.reachable = false;
         if (!var->gc.info.start_gc)  // 未启用gc但却在gc链中
             return false;
@@ -235,12 +235,16 @@ static void freeValue(af_Core *core) {
     }
 }
 
-
 #define GC_ADD_FUNC_DEFINED(type) \
-void gc_add##type(af_##type *obj, af_Core *core) { \
+void gc_add##type(af_##type *obj, af_Environment *env) { \
     obj->gc.prev = NULL; \
-    obj->gc.next = core->gc_##type; \
-    core->gc_##type = obj; \
+    obj->gc.next = env->core->gc_##type; \
+    env->core->gc_##type = obj; \
+} \
+void gc_add##type##ByCore(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)
@@ -254,7 +258,7 @@ bool gc_RunGC(af_Environment *env) {
     gc_Analyzed *analyzed;
     pgc_Analyzed plist = &analyzed;
 
-    if (!resetGC(env->core))
+    if (!resetGC(env))
         return false;
 
     plist = iterLinker(env->core, plist);  // 临时量分析 (临时量都是通过reference标记的)
@@ -284,3 +288,24 @@ bool gc_RunGC(af_Environment *env) {
     return true;
 }
 
+void gc_freeAllValue(af_Core *core) {
+    for (af_ObjectData *od = core->gc_ObjectData, *next; od != NULL; od = next) {
+        next = od->gc.next;
+        freeObjectData(od);  // 暂时不考虑析构函数
+    }
+
+    for (af_Object *obj = core->gc_Object, *next; obj != NULL; obj = next) {
+        next = obj->gc.next;
+        freeObject(obj);
+    }
+
+    for (af_VarSpace *vs = core->gc_VarSpace, *next; vs != NULL; vs = next) {
+        next = vs->gc.next;
+        freeVarSpace(vs);
+    }
+
+    for (af_Var *var = core->gc_Var, *next; var != NULL; var = next) {
+        next = var->gc.next;
+        freeVar(var);
+    }
+}

+ 4 - 4
src/core/object.c

@@ -57,15 +57,15 @@ af_Object *makeObject(char *id, size_t data_size, bool inherit_api, bool allow_i
         obj->belong = env->activity->belong;
 
     if (!env->core->in_init && inherit == NULL) {
-        obj->data->iherit = makenIherit(env->core->object);
+        obj->data->iherit = makeIherit(env->core->object);
     } else
         obj->data->iherit = inherit;
 
     if (!env->core->in_init && inherit_api)
         obj->data->api = obj->data->iherit->obj->data->api;
 
-    gc_addObjectData(obj->data, env->core);
-    gc_addObject(obj, env->core);
+    gc_addObjectData(obj->data, env);
+    gc_addObject(obj, env);
     return obj;
 }
 
@@ -92,7 +92,7 @@ void freeObject(af_Object *obj) {
     free(obj);
 }
 
-af_Inherit *makenIherit(af_Object *obj) {
+af_Inherit *makeIherit(af_Object *obj) {
     af_Inherit *ih = calloc(sizeof(af_Inherit), 1);
     ih->obj = obj;
     return ih;

+ 31 - 4
src/core/var.c

@@ -1,4 +1,5 @@
 #include "__var.h"
+#include "__env.h"
 #include "tool.h"
 
 static af_VarNode *makeVarNode(af_Object *obj, char *id);
@@ -108,20 +109,36 @@ void freeAllVarSpaceList(af_VarSpaceListNode *vsl) {
         vsl = freeVarSpaceList(vsl);
 }
 
-void addVarSpaceGC(af_VarSpace *vs, af_Core *core) {
+void addVarSpaceGCByCore(af_VarSpace *vs, af_Core *core) {
     if (vs->gc.info.start_gc)
         return;
 
     vs->gc.info.start_gc = true;
-    gc_addVarSpace(vs, core);
+    gc_addVarSpaceByCore(vs, core);
 }
 
-void addVarGC(af_Var *var, af_Core *core) {
+void addVarSpaceGC(af_VarSpace *vs, af_Environment *env) {
+    if (vs->gc.info.start_gc)
+        return;
+
+    vs->gc.info.start_gc = true;
+    gc_addVarSpace(vs, env);
+}
+
+void addVarGCByCore(af_Var *var, af_Core *core) {
+    if (var->gc.info.start_gc)
+        return;
+
+    var->gc.info.start_gc = true;
+    gc_addVarByCore(var, core);
+}
+
+void addVarGC(af_Var *var, af_Environment *env) {
     if (var->gc.info.start_gc)
         return;
 
     var->gc.info.start_gc = true;
-    gc_addVar(var, core);
+    gc_addVar(var, env);
 }
 
 /*
@@ -190,3 +207,13 @@ af_Var *findVarFromVarList(char *name, af_VarSpaceListNode *vsl) {
 
     return NULL;
 }
+
+af_VarSpaceListNode *pushNewVarList(af_VarSpaceListNode *base) {
+    af_VarSpaceListNode *new = makeVarSpaceList(makeVarSpace());
+    new->next = base;
+    return new;
+}
+
+af_VarSpaceListNode *popLastVarList(af_VarSpaceListNode *base) {
+    return freeVarSpaceList(base);
+}