瀏覽代碼

feat: 加入变量权限管理

访问变量时检查权限
VarSpace设置属主
权限设置: 自身权限, 后代权限和外部权限
SongZihuan 3 年之前
父節點
當前提交
450527e58e
共有 13 個文件被更改,包括 153 次插入99 次删除
  1. 3 3
      include/obj_api.h
  2. 4 2
      include/object.h
  3. 9 8
      include/var.h
  4. 1 1
      src/core/__object.h
  5. 4 3
      src/core/__var.h
  6. 5 5
      src/core/env.c
  7. 1 1
      src/core/func.c
  8. 4 2
      src/core/gc.c
  9. 33 23
      src/core/object.c
  10. 3 3
      src/core/run.c
  11. 54 16
      src/core/var.c
  12. 22 22
      src/main.c
  13. 10 10
      test/test_env.c

+ 3 - 3
include/obj_api.h

@@ -25,9 +25,9 @@ typedef struct af_FuncBody *callFuncBody(void *mark, af_Environment *env);  // 
 
 
 /* 定义Object的函数签名 */
 /* 定义Object的函数签名 */
 /* Object void *data 管理 */
 /* 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_destructData(char *id, void *data, af_Environment *env);  // 释放data的内容 (但不释放void *data)指针
+typedef size_t obj_getDataSize(af_Object *obj);  // 获取data的大小
+typedef void obj_initData(af_Object *obj, void *data, af_Environment *env);  // 初始化data
+typedef void obj_destructData(af_Object *obj, void *data, af_Environment *env);  // 释放data的内容 (但不释放void *data)指针
 
 
 /* Object 面向对象管理 */
 /* Object 面向对象管理 */
 typedef af_VarSpace *obj_getShareVarSpace(af_Object *obj);
 typedef af_VarSpace *obj_getShareVarSpace(af_Object *obj);

+ 4 - 2
include/object.h

@@ -21,15 +21,17 @@ void freeObject(af_Object *obj, af_Environment *env);
 /* 对象属性获取函数 */
 /* 对象属性获取函数 */
 void *getObjectData(af_Object *obj);
 void *getObjectData(af_Object *obj);
 af_Object *getBelongObject(af_Object *object);
 af_Object *getBelongObject(af_Object *object);
-af_Object *findObjectAttributes(char *name, af_Object *obj);
+af_Object *findObjectAttributes(char *name, af_Object *visitor, af_Object *obj);
 
 
 /* 对象属性设置 */
 /* 对象属性设置 */
-bool setObjectAttributes(char *name, char p_self, char p_external, af_Object *attributes, af_Object *obj, af_Environment *env);
+bool setObjectAttributes(char *name, char p_self, char p_posterity, char p_external, af_Object *attributes,
+                         af_Object *obj, af_Environment *env);
 
 
 /* 对象继承关系函数 */
 /* 对象继承关系函数 */
 af_Inherit *makeInherit(af_Object *obj);
 af_Inherit *makeInherit(af_Object *obj);
 af_Inherit *freeInherit(af_Inherit *ih);
 af_Inherit *freeInherit(af_Inherit *ih);
 void freeAllInherit(af_Inherit *ih);
 void freeAllInherit(af_Inherit *ih);
+bool checkPosterity(af_Object *base, af_Object *posterity);
 
 
 /* API表 创建与释放 */
 /* API表 创建与释放 */
 af_ObjectAPI *makeObjectAPI(void);
 af_ObjectAPI *makeObjectAPI(void);

+ 9 - 8
include/var.h

@@ -9,26 +9,27 @@ typedef struct af_VarSpaceListNode af_VarSpaceListNode;
 #include "object.h"
 #include "object.h"
 
 
 /* 变量创建与释放 */
 /* 变量创建与释放 */
-af_Var *makeVar(char *name, char p_self, char p_external, af_Object *obj, af_Environment *env);
+af_Var *makeVar(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_Environment *env);
 void freeVar(af_Var *var, af_Environment *env);
 void freeVar(af_Var *var, af_Environment *env);
 
 
 /* 变量值管理 */
 /* 变量值管理 */
 void addVarNode(af_Var var, af_Object *obj, char *id);
 void addVarNode(af_Var var, af_Object *obj, char *id);
 
 
 /* 变量空间创建与释放 */
 /* 变量空间创建与释放 */
-af_VarSpace *makeVarSpace(af_Environment *env);
+af_VarSpace *makeVarSpace(af_Object *belong, af_Environment *env);
 void freeVarSpace(af_VarSpace *vs, af_Environment *env);
 void freeVarSpace(af_VarSpace *vs, af_Environment *env);
 
 
 /* 变量赋值类函数 */
 /* 变量赋值类函数 */
 bool addVarToVarSpace(af_Var *var, af_VarSpace *vs);
 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 makeVarToVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_VarSpace *vs,
+                       af_Environment *env);
 bool addVarToVarSpaceList(af_Var *var, af_VarSpaceListNode *vsl);
 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_posterity, char p_external, af_Object *obj,
+                           af_VarSpaceListNode *vsl, af_Environment *env);
 
 
 /* 变量寻值类函数 */
 /* 变量寻值类函数 */
-af_Var *findVarFromVarSpace(char *name, af_VarSpace *vs);
-af_Var *findVarFromVarList(char *name, af_VarSpaceListNode *vsl);
-
+af_Var *findVarFromVarSpace(char *name, af_Object *visitor, af_VarSpace *vs);
+af_Var *findVarFromVarList(char *name, af_Object *visitor, af_VarSpaceListNode *vsl);
 /* 变量空间链的创建与释放 */
 /* 变量空间链的创建与释放 */
 af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs);
 af_VarSpaceListNode *makeVarSpaceList(af_VarSpace *vs);
 af_VarSpaceListNode *freeVarSpaceList(af_VarSpaceListNode *vsl);
 af_VarSpaceListNode *freeVarSpaceList(af_VarSpaceListNode *vsl);
@@ -39,7 +40,7 @@ bool freeVarSpaceListCount(size_t count, af_VarSpaceListNode *vsl);
 af_VarSpace *getVarSpaceFromList(af_VarSpaceListNode *vsl);
 af_VarSpace *getVarSpaceFromList(af_VarSpaceListNode *vsl);
 
 
 /* 变量空间链管理 */
 /* 变量空间链管理 */
-af_VarSpaceListNode *pushNewVarList(af_VarSpaceListNode *base, af_Environment *env);
+af_VarSpaceListNode *pushNewVarList(af_Object *belong, af_VarSpaceListNode *base, af_Environment *env);
 af_VarSpaceListNode *popLastVarList(af_VarSpaceListNode *base);
 af_VarSpaceListNode *popLastVarList(af_VarSpaceListNode *base);
 
 
 #endif //AFUN__VAR_H_PUBLIC
 #endif //AFUN__VAR_H_PUBLIC

+ 1 - 1
src/core/__object.h

@@ -61,7 +61,7 @@ struct af_Inherit {
 };
 };
 
 
 /* ObjectData 属性获取函数 */
 /* ObjectData 属性获取函数 */
-af_Object *findObjectAttributesByObjectData(char *name, af_ObjectData *od);
+af_Object *findObjectAttributesByObjectData(char *name, af_Object *visitor, af_ObjectData *od);
 
 
 /* ObjectData 释放函数 */
 /* ObjectData 释放函数 */
 void freeObjectData(af_ObjectData *od, af_Environment *env);
 void freeObjectData(af_ObjectData *od, af_Environment *env);

+ 4 - 3
src/core/__var.h

@@ -20,7 +20,7 @@ struct af_VarNode {
 struct af_Var {
 struct af_Var {
     char *name;
     char *name;
     struct af_VarNode *vn;
     struct af_VarNode *vn;
-    char permissions[2];  // 读-1 写-2 读且写-3 不读不写-0 [自身权限 外部权限]
+    char permissions[3];  // 读-1 写-2 读且写-3 不读不写-0 [自身权限 后代权限 外部权限]
     GC_Var gc;
     GC_Var gc;
 };
 };
 
 
@@ -32,6 +32,7 @@ struct af_VarCup {
 struct af_VarSpace {
 struct af_VarSpace {
     bool is_protect;  // 是否为保护变量空间
     bool is_protect;  // 是否为保护变量空间
     struct af_VarCup *(var[VAR_HASHTABLE_SIZE]);
     struct af_VarCup *(var[VAR_HASHTABLE_SIZE]);
+    struct af_Object *belong;  // 属主
     GC_VarSpace gc;
     GC_VarSpace gc;
 };
 };
 
 
@@ -41,11 +42,11 @@ struct af_VarSpaceListNode {  // 变量链
 };
 };
 
 
 /* 变量空间创建与释放 */
 /* 变量空间创建与释放 */
-af_VarSpace *makeVarSpaceByCore(af_Core *core);
+af_VarSpace *makeVarSpaceByCore(af_Object *belong, af_Core *core);
 void freeVarSpaceByCore(af_VarSpace *vs, af_Core *core);
 void freeVarSpaceByCore(af_VarSpace *vs, af_Core *core);
 
 
 /* 变量创建与释放 */
 /* 变量创建与释放 */
-af_Var *makeVarByCore(char *name, char p_self, char p_external, af_Object *obj, af_Core *core);
+af_Var *makeVarByCore(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_Core *core);
 void freeVarByCore(af_Var *var, af_Core *core);
 void freeVarByCore(af_Var *var, af_Core *core);
 
 
 #endif //AFUN__VAR_H
 #endif //AFUN__VAR_H

+ 5 - 5
src/core/env.c

@@ -42,7 +42,7 @@ static af_LiteralDataList *freeLiteralData_Pri(af_LiteralDataList *ld);
 static af_Core *makeCore(enum GcRunTime grt) {
 static af_Core *makeCore(enum GcRunTime grt) {
     af_Core *core = calloc(sizeof(af_Core), 1);
     af_Core *core = calloc(sizeof(af_Core), 1);
     core->in_init = true;
     core->in_init = true;
-    core->protect = makeVarSpaceByCore(core);
+    core->protect = makeVarSpaceByCore(NULL, core);
 
 
     core->prefix[V_QUOTE] = '\'';
     core->prefix[V_QUOTE] = '\'';
     core->prefix[B_EXEC] = '\'';
     core->prefix[B_EXEC] = '\'';
@@ -98,7 +98,7 @@ af_VarSpace *getProtectVarSpace(af_Environment *env) {
  * 作用: 用于init初始化时在保护空间获得一些初始化对象
  * 作用: 用于init初始化时在保护空间获得一些初始化对象
  */
  */
 af_Object *getBaseObjectFromCore(char *name, af_Core *core) {
 af_Object *getBaseObjectFromCore(char *name, af_Core *core) {
-    af_Var *var = findVarFromVarSpace(name, core->protect);
+    af_Var *var = findVarFromVarSpace(name, NULL, core->protect);
     if (var != NULL)
     if (var != NULL)
         return var->vn->obj;
         return var->vn->obj;
     return NULL;
     return NULL;
@@ -741,21 +741,21 @@ bool setFuncActivityAddVar(af_Environment *env){
     }
     }
 
 
     if (env->activity->fi->embedded != super_embedded) {  // 不是超内嵌函数则引入一层新的变量空间
     if (env->activity->fi->embedded != super_embedded) {  // 不是超内嵌函数则引入一层新的变量空间
-        env->activity->var_list = pushNewVarList(env->activity->var_list, env);
+        env->activity->var_list = pushNewVarList(env->activity->func, env->activity->var_list, env);
         env->activity->new_vs_count++;
         env->activity->new_vs_count++;
     }
     }
 
 
     env->activity->func_var_list = NULL;
     env->activity->func_var_list = NULL;
 
 
     if (env->activity->fi->var_this && env->activity->belong != NULL) {
     if (env->activity->fi->var_this && env->activity->belong != NULL) {
-        if (!makeVarToVarSpaceList("this", 3, 3, env->activity->belong, env->activity->var_list, env)) {
+        if (!makeVarToVarSpaceList("this", 3, 3, 3, env->activity->belong, env->activity->var_list, env)) {
             pushMessageDown(makeMessage("ERROR-STR", 0), env);
             pushMessageDown(makeMessage("ERROR-STR", 0), env);
             return false;
             return false;
         }
         }
     }
     }
 
 
     if (env->activity->fi->var_func && env->activity->func != NULL) {
     if (env->activity->fi->var_func && env->activity->func != NULL) {
-        if (!makeVarToVarSpaceList("func", 3, 3, env->activity->func, env->activity->var_list, env)) {
+        if (!makeVarToVarSpaceList("func", 3, 3, 3, env->activity->func, env->activity->var_list, env)) {
             pushMessageDown(makeMessage("ERROR-STR", 0), env);
             pushMessageDown(makeMessage("ERROR-STR", 0), env);
             return false;
             return false;
         }
         }

+ 1 - 1
src/core/func.c

@@ -101,7 +101,7 @@ af_ArgList **pushNewArgList(af_ArgList **base, char *name, af_Object *obj) {
 
 
 bool runArgList(af_ArgList *al, af_VarSpaceListNode *vsl, af_Environment *env){
 bool runArgList(af_ArgList *al, af_VarSpaceListNode *vsl, af_Environment *env){
     for (NULL; al != NULL; al = al->next) {
     for (NULL; al != NULL; al = al->next) {
-        if (!makeVarToVarSpaceList(al->name, 3, 3, al->obj, vsl, env))
+        if (!makeVarToVarSpaceList(al->name, 3, 3, 3, al->obj, vsl, env))
             return false;
             return false;
     }
     }
     return true;
     return true;

+ 4 - 2
src/core/gc.c

@@ -205,6 +205,8 @@ static pgc_Analyzed reachableVarSpace(struct af_VarSpace *vs, pgc_Analyzed plist
         return plist;
         return plist;
 
 
     vs->gc.info.reachable = true;
     vs->gc.info.reachable = true;
+    if (vs->belong != NULL)
+        plist = makeAnalyzed(vs->belong, plist);
     for (int i = 0; i < VAR_HASHTABLE_SIZE; i++) {
     for (int i = 0; i < VAR_HASHTABLE_SIZE; i++) {
         for (af_VarCup *var = vs->var[i]; var != NULL; var = var->next)
         for (af_VarCup *var = vs->var[i]; var != NULL; var = var->next)
             plist = reachableVar(var->var, plist);
             plist = reachableVar(var->var, plist);
@@ -341,7 +343,7 @@ static void freeValue(af_Environment *env) {
 static pgc_Analyzed checkDestruct(af_Environment *env, pgc_DestructList *pdl, pgc_Analyzed plist) {
 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) {
     for (af_ObjectData *od = env->core->gc_ObjectData; od != NULL; od = od->gc.next) {
         if (!od->gc.info.reachable && !od->gc.done_destruct) {
         if (!od->gc.info.reachable && !od->gc.done_destruct) {
-            af_Object *func = findObjectAttributesByObjectData(gc_destruct, od);
+            af_Object *func = findObjectAttributesByObjectData(gc_destruct, NULL, od);
             if (func == NULL)
             if (func == NULL)
                 continue;
                 continue;
             od->gc.done_destruct = true;
             od->gc.done_destruct = true;
@@ -374,7 +376,7 @@ void gc_RunGC(af_Environment *env) {
 pgc_DestructList checkAllDestruct(af_Environment *env, pgc_DestructList pdl) {
 pgc_DestructList checkAllDestruct(af_Environment *env, pgc_DestructList pdl) {
     for (af_ObjectData *od = env->core->gc_ObjectData; od != NULL; od = od->gc.next) {
     for (af_ObjectData *od = env->core->gc_ObjectData; od != NULL; od = od->gc.next) {
         if (!od->gc.done_destruct) {
         if (!od->gc.done_destruct) {
-            af_Object *func = findObjectAttributesByObjectData(gc_destruct, od);
+            af_Object *func = findObjectAttributesByObjectData(gc_destruct, NULL, od);
             if (func == NULL)
             if (func == NULL)
                 continue;
                 continue;
             od->gc.done_destruct = true;
             od->gc.done_destruct = true;

+ 33 - 23
src/core/object.c

@@ -3,7 +3,8 @@
 #include "tool.h"
 #include "tool.h"
 
 
 /* ObjectData 创建与释放 */
 /* 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_Object *base_obj,
+                                          af_Environment *env);
 static af_Object *makeObject_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 创建与释放 */
 /* ObjectData API 创建与释放 */
@@ -21,32 +22,33 @@ static int addAPIToObjectData(DLC_SYMBOL(objectAPIFunc) func, char *api_name, af
  * 注意: af_ObjectData不是对外开放的结构体
  * 注意: af_ObjectData不是对外开放的结构体
  * 注意: api不能为NULL
  * 注意: api不能为NULL
  */
  */
-static af_ObjectData * makeObjectData_Pri(char *id, bool free_api, af_ObjectAPI *api, bool allow_inherit,
+static af_ObjectData * makeObjectData_Pri(char *id, bool free_api, af_ObjectAPI *api, bool allow_inherit, af_Object *base_obj,
                                           af_Environment *env){
                                           af_Environment *env){
     af_ObjectData *od = calloc(sizeof(af_ObjectData), 1);
     af_ObjectData *od = calloc(sizeof(af_ObjectData), 1);
+    od->base = base_obj;
+    base_obj->data = od;
     od->id = strCopy(id == NULL ? "Unknow" : id);
     od->id = strCopy(id == NULL ? "Unknow" : id);
 
 
+    od->api = api;
+    od->free_api = free_api;
+    od->allow_inherit = allow_inherit;
+
+    od->var_space = makeVarSpace(base_obj, env);
+    od->inherit = NULL;
+
     obj_getDataSize *func = findAPI("obj_getDataSize", api);
     obj_getDataSize *func = findAPI("obj_getDataSize", api);
     obj_initData *init = findAPI("obj_initData", api);
     obj_initData *init = findAPI("obj_initData", api);
     if (func != NULL)
     if (func != NULL)
-        od->size = func(od->id);
+        od->size = func(base_obj);
     else
     else
         od->size = 0;
         od->size = 0;
 
 
     if (od->size != 0) {
     if (od->size != 0) {
         od->data = calloc(od->size, 1);
         od->data = calloc(od->size, 1);
         if (init != NULL)
         if (init != NULL)
-            init(od->id, od->data, env);
+            init(base_obj, od->data, env);
     }
     }
 
 
-    od->api = api;
-    od->free_api = free_api;
-    od->allow_inherit = allow_inherit;
-
-    od->var_space = makeVarSpace(env);
-    od->inherit = NULL;
-
-    od->base = NULL;
     gc_addObjectData(od, env);
     gc_addObjectData(od, env);
     return od;
     return od;
 }
 }
@@ -54,8 +56,7 @@ static af_ObjectData * makeObjectData_Pri(char *id, bool free_api, af_ObjectAPI
 static af_Object *makeObject_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){
     af_Object *obj = calloc(sizeof(af_Object), 1);
     af_Object *obj = calloc(sizeof(af_Object), 1);
     obj->belong = NULL;
     obj->belong = NULL;
-    obj->data = makeObjectData_Pri(id, free_api, api, allow_inherit, env);
-    obj->data->base = obj;
+    makeObjectData_Pri(id, free_api, api, allow_inherit, obj, env);
     gc_addObject(obj, env);
     gc_addObject(obj, env);
     return obj;
     return obj;
 }
 }
@@ -101,7 +102,7 @@ void freeObjectData(af_ObjectData *od, af_Environment *env) {
     if (od->size != 0) {
     if (od->size != 0) {
         obj_destructData *func = findAPI("obj_destructData", od->api);
         obj_destructData *func = findAPI("obj_destructData", od->api);
         if (func != NULL)
         if (func != NULL)
-            func(od->id, od->data, env);
+            func(od->base, od->data, env);
     }
     }
 
 
     free(od->id);
     free(od->id);
@@ -159,6 +160,14 @@ void freeAllInherit(af_Inherit *ih) {
         ih = freeInherit(ih);
         ih = freeInherit(ih);
 }
 }
 
 
+bool checkPosterity(af_Object *base, af_Object *posterity) {
+    for (af_Inherit *ih = base->data->inherit; ih != NULL; ih = ih->next) {
+        if (ih->obj->data == posterity->data)
+            return true;
+    }
+    return false;
+}
+
 static af_ObjectAPINode *makeObjectAPINode(DLC_SYMBOL(objectAPIFunc) func, char *api_name) {
 static af_ObjectAPINode *makeObjectAPINode(DLC_SYMBOL(objectAPIFunc) func, char *api_name) {
     if (func == NULL)
     if (func == NULL)
         return NULL;
         return NULL;
@@ -274,14 +283,14 @@ void *findObjectAPI(char *api_name, af_Object *obj) {
     return GET_SYMBOL(node->api);
     return GET_SYMBOL(node->api);
 }
 }
 
 
-af_Object *findObjectAttributes(char *name, af_Object *obj) {
-    af_Var *var = findVarFromVarSpace(name, obj->data->var_space);
+af_Object *findObjectAttributes(char *name, af_Object *visitor, af_Object *obj) {
+    af_Var *var = findVarFromVarSpace(name, visitor, obj->data->var_space);
 
 
     if (var != NULL)
     if (var != NULL)
         return var->vn->obj;
         return var->vn->obj;
 
 
     for (af_Inherit *ih = obj->data->inherit; ih != NULL; ih = ih->next) {
     for (af_Inherit *ih = obj->data->inherit; ih != NULL; ih = ih->next) {
-        var = findVarFromVarSpace(name, ih->vs);  // 搜索共享变量空间
+        var = findVarFromVarSpace(name, visitor, ih->vs);  // 搜索共享变量空间
         if (var != NULL)
         if (var != NULL)
             return var->vn->obj;
             return var->vn->obj;
     }
     }
@@ -289,18 +298,19 @@ af_Object *findObjectAttributes(char *name, af_Object *obj) {
     return NULL;
     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);
+bool setObjectAttributes(char *name, char p_self, char p_posterity, char p_external, af_Object *attributes,
+                         af_Object *obj, af_Environment *env){
+    return makeVarToVarSpace(name, p_self, p_posterity, p_external, attributes, obj->data->var_space, env);
 }
 }
 
 
-af_Object *findObjectAttributesByObjectData(char *name, af_ObjectData *od) {
-    af_Var *var = findVarFromVarSpace(name, od->var_space);
+af_Object *findObjectAttributesByObjectData(char *name, af_Object *visitor, af_ObjectData *od) {
+    af_Var *var = findVarFromVarSpace(name, visitor, od->var_space);
 
 
     if (var != NULL)
     if (var != NULL)
         return var->vn->obj;
         return var->vn->obj;
 
 
     for (af_Inherit *ih = od->inherit; ih != NULL; ih = ih->next) {
     for (af_Inherit *ih = od->inherit; ih != NULL; ih = ih->next) {
-        var = findVarFromVarSpace(name, ih->vs);  // 搜索共享变量空间
+        var = findVarFromVarSpace(name, visitor, ih->vs);  // 搜索共享变量空间
         if (var != NULL)
         if (var != NULL)
             return var->vn->obj;
             return var->vn->obj;
     }
     }

+ 3 - 3
src/core/run.c

@@ -121,7 +121,7 @@ static bool iterCodeInit(af_Code *code, af_Environment *env) {
  * 返回-true  表示执行成功, 得到一个对象函数, 并且隐式调用 (msg_down中无消息写入, 函数仅设置activity无实质性代码执行)
  * 返回-true  表示执行成功, 得到一个对象函数, 并且隐式调用 (msg_down中无消息写入, 函数仅设置activity无实质性代码执行)
  */
  */
 static bool codeVariable(af_Code *code, af_Environment *env) {
 static bool codeVariable(af_Code *code, af_Environment *env) {
-    af_Var *var = findVarFromVarList(code->variable.name, env->activity->vsl);
+    af_Var *var = findVarFromVarList(code->variable.name, env->activity->belong, env->activity->vsl);
 
 
     if (var == NULL) {
     if (var == NULL) {
         pushMessageDown(makeMessage("ERROR-STR", 0), env);
         pushMessageDown(makeMessage("ERROR-STR", 0), env);
@@ -151,9 +151,9 @@ static bool codeVariable(af_Code *code, af_Environment *env) {
 static bool codeLiteral(af_Code *code, af_Environment *env) {
 static bool codeLiteral(af_Code *code, af_Environment *env) {
     af_Var *var;
     af_Var *var;
     if (code->literal.in_protect)
     if (code->literal.in_protect)
-        var = findVarFromVarSpace(code->literal.func, env->core->protect);
+        var = findVarFromVarSpace(code->literal.func, env->activity->belong, env->core->protect);
     else
     else
-        var = findVarFromVarList(code->literal.func, env->activity->vsl);
+        var = findVarFromVarList(code->literal.func, env->activity->belong, env->activity->vsl);
 
 
     if (var == NULL) {
     if (var == NULL) {
         pushMessageDown(makeMessage("ERROR-STR", 0), env);
         pushMessageDown(makeMessage("ERROR-STR", 0), env);

+ 54 - 16
src/core/var.c

@@ -14,6 +14,7 @@ static void freeAllVarCup(af_VarCup *vp);
 
 
 /* VarSpace 寻值函数 */
 /* VarSpace 寻值函数 */
 static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpace *vs);
 static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpace *vs);
+static bool checkReadPermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs);
 
 
 static af_VarNode *makeVarNode(af_Object *obj, char *id) {
 static af_VarNode *makeVarNode(af_Object *obj, char *id) {
     af_VarNode *vn = calloc(sizeof(af_VarNode), 1);
     af_VarNode *vn = calloc(sizeof(af_VarNode), 1);
@@ -35,23 +36,25 @@ static void freeAllVarNode(af_VarNode *vn) {
         vn = freeVarNode(vn);
         vn = freeVarNode(vn);
 }
 }
 
 
-af_Var *makeVar(char *name, char p_self, char p_external, af_Object *obj, af_Environment *env) {
+af_Var *makeVar(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_Environment *env){
     af_VarNode *vn = makeVarNode(obj, NULL);
     af_VarNode *vn = makeVarNode(obj, NULL);
     af_Var *var = calloc(sizeof(af_Var), 1);
     af_Var *var = calloc(sizeof(af_Var), 1);
     var->name = strCopy(name);
     var->name = strCopy(name);
     var->vn = vn;
     var->vn = vn;
     var->permissions[0] = p_self;
     var->permissions[0] = p_self;
-    var->permissions[1] = p_external;
+    var->permissions[1] = p_posterity;
+    var->permissions[2] = p_external;
     gc_addVar(var, env);
     gc_addVar(var, env);
     return var;
     return var;
 }
 }
 
 
-af_Var *makeVarByCore(char *name, char p_self, char p_external, af_Object *obj, af_Core *core) {
+af_Var *makeVarByCore(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_Core *core){
     af_VarNode *vn = makeVarNode(obj, NULL);
     af_VarNode *vn = makeVarNode(obj, NULL);
     af_Var *var = calloc(sizeof(af_Var), 1);
     af_Var *var = calloc(sizeof(af_Var), 1);
     var->name = strCopy(name);
     var->name = strCopy(name);
     var->vn = vn;
     var->vn = vn;
     var->permissions[0] = p_self;
     var->permissions[0] = p_self;
+    var->permissions[1] = p_posterity;
     var->permissions[1] = p_external;
     var->permissions[1] = p_external;
     gc_addVarByCore(var, core);
     gc_addVarByCore(var, core);
     return var;
     return var;
@@ -94,14 +97,22 @@ static void freeAllVarCup(af_VarCup *vp) {
         vp = freeVarCup(vp);
         vp = freeVarCup(vp);
 }
 }
 
 
-af_VarSpace *makeVarSpace(af_Environment *env) {
+af_VarSpace *makeVarSpace(af_Object *belong, af_Environment *env) {
+    if (!env->core->in_init && belong == NULL)
+        return NULL;
+
     af_VarSpace *vs = calloc(sizeof(af_VarSpace), 1);
     af_VarSpace *vs = calloc(sizeof(af_VarSpace), 1);
+    vs->belong = belong;
     gc_addVarSpace(vs, env);
     gc_addVarSpace(vs, env);
     return vs;
     return vs;
 }
 }
 
 
-af_VarSpace *makeVarSpaceByCore(af_Core *core) {
+af_VarSpace *makeVarSpaceByCore(af_Object *belong, af_Core *core) {
+    if (!core->in_init && belong == NULL)
+        return NULL;
+
     af_VarSpace *vs = calloc(sizeof(af_VarSpace), 1);
     af_VarSpace *vs = calloc(sizeof(af_VarSpace), 1);
+    vs->belong = belong;
     gc_addVarSpaceByCore(vs, core);
     gc_addVarSpaceByCore(vs, core);
     return vs;
     return vs;
 }
 }
@@ -180,8 +191,9 @@ bool addVarToVarSpace(af_Var *var, af_VarSpace *vs) {
  * 若已存在同名Var则返回false不作修改
  * 若已存在同名Var则返回false不作修改
  * 否则返回true
  * 否则返回true
  */
  */
-bool makeVarToVarSpace(char *name, char p_self, char p_external, af_Object *obj, af_VarSpace *vs, af_Environment *env){
-    return addVarToVarSpace(makeVar(name, p_self, p_external, obj, env), vs);
+bool makeVarToVarSpace(char *name, char p_self, char p_posterity, char p_external, af_Object *obj, af_VarSpace *vs,
+                       af_Environment *env){
+    return addVarToVarSpace(makeVar(name, p_self, p_posterity, p_external, obj, env), vs);
 }
 }
 
 
 bool addVarToVarSpaceList(af_Var *var, af_VarSpaceListNode *vsl) {
 bool addVarToVarSpaceList(af_Var *var, af_VarSpaceListNode *vsl) {
@@ -192,13 +204,15 @@ bool addVarToVarSpaceList(af_Var *var, af_VarSpaceListNode *vsl) {
     return false;
     return false;
 }
 }
 
 
-bool makeVarToVarSpaceList(char *name, char p_self, char p_external, af_Object *obj, af_VarSpaceListNode *vsl, af_Environment *env){
-    return addVarToVarSpaceList(makeVar(name, p_self, p_external, obj, env), vsl);
+bool makeVarToVarSpaceList(char *name, char p_self, char p_posterity, char p_external, af_Object *obj,
+                           af_VarSpaceListNode *vsl, af_Environment *env){
+    return addVarToVarSpaceList(makeVar(name, p_self, p_posterity, p_external, obj, env), vsl);
 }
 }
 
 
 /*
 /*
  * 函数名: findVarFromVarSpaceByIndex
  * 函数名: findVarFromVarSpaceByIndex
  * 目标: 根据指定的index, 在VarSpace中搜索var
  * 目标: 根据指定的index, 在VarSpace中搜索var
+ * 权限检查交给 findVarFromVarSpace 和 findVarFromVarList
  */
  */
 static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpace *vs) {
 static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpace *vs) {
     for (af_VarCup *cup = vs->var[index]; cup != NULL; cup = cup->next) {
     for (af_VarCup *cup = vs->var[index]; cup != NULL; cup = cup->next) {
@@ -208,33 +222,57 @@ static af_Var *findVarFromVarSpaceByIndex(time33_t index, char *name, af_VarSpac
     return NULL;
     return NULL;
 }
 }
 
 
+static bool checkReadPermissions(af_Var *var, af_Object *visitor, af_VarSpace *vs){
+    char p = var->permissions[2];  // 默认外部权限
+
+    if (vs->belong == NULL || (visitor != NULL && vs->belong->data == visitor->data))  // (无权限设定或ObjectData匹配) 应用自身权限
+        p = var->permissions[0];
+    else if (visitor != NULL && checkPosterity(vs->belong, visitor))  // 应用后代权限
+        p = var->permissions[1];
+
+    return p == 1 || p == 3;
+}
+
 /*
 /*
  * 函数名: findVarFromVarSpace
  * 函数名: findVarFromVarSpace
  * 目标: 在VarSpace中搜索var
  * 目标: 在VarSpace中搜索var
+ * 调用: findVarFromVarSpaceByIndex
  */
  */
-af_Var *findVarFromVarSpace(char *name, af_VarSpace *vs) {
-    return findVarFromVarSpaceByIndex(time33(name) % VAR_HASHTABLE_SIZE, name, vs);
+af_Var *findVarFromVarSpace(char *name, af_Object *visitor, af_VarSpace *vs){
+    af_Var *var = findVarFromVarSpaceByIndex(time33(name) % VAR_HASHTABLE_SIZE, name, vs);
+    if (var == NULL)
+        return NULL;
+
+    if (checkReadPermissions(var, visitor, vs))
+        return var;
+    else
+        return NULL;
 }
 }
 
 
 /*
 /*
  * 函数名: findVarFromVarList
  * 函数名: findVarFromVarList
  * 目标: 在VarSpaceListNode中搜索var
  * 目标: 在VarSpaceListNode中搜索var
+ * 调用: findVarFromVarSpaceByIndex
  */
  */
-af_Var *findVarFromVarList(char *name, af_VarSpaceListNode *vsl) {
+af_Var *findVarFromVarList(char *name, af_Object *visitor, af_VarSpaceListNode *vsl) {
     time33_t index = time33(name) % VAR_HASHTABLE_SIZE;
     time33_t index = time33(name) % VAR_HASHTABLE_SIZE;
     af_Var *var = NULL;
     af_Var *var = NULL;
 
 
     for (NULL; vsl != NULL; vsl = vsl->next) {
     for (NULL; vsl != NULL; vsl = vsl->next) {
         var = findVarFromVarSpaceByIndex(index, name, vsl->vs);
         var = findVarFromVarSpaceByIndex(index, name, vsl->vs);
-        if (var != NULL)
-            return var;
+        if (var != NULL) {
+            if (checkReadPermissions(var, visitor, vsl->vs))
+                return var;
+            else
+                return NULL;
+        }
     }
     }
 
 
     return NULL;
     return NULL;
 }
 }
 
 
-af_VarSpaceListNode *pushNewVarList(af_VarSpaceListNode *base, af_Environment *env){
-    af_VarSpaceListNode *new = makeVarSpaceList(makeVarSpace(env));
+af_VarSpaceListNode *pushNewVarList(af_Object *belong, af_VarSpaceListNode *base, af_Environment *env){
+    af_VarSpaceListNode *new = makeVarSpaceList(makeVarSpace(belong, env));
     new->next = base;
     new->next = base;
     return new;
     return new;
 }
 }

+ 22 - 22
src/main.c

@@ -12,42 +12,42 @@ void mp_ERROR_STR(af_Message *msg, bool is_gc, af_Environment *env) {
     free(*pinfo);
     free(*pinfo);
 }
 }
 
 
-size_t getSize(char *id) {
+size_t getSize(af_Object *obj) {
     return sizeof(int *);
     return sizeof(int *);
 }
 }
 
 
-void initData(char *id, int **data, af_Environment *env) {
+void initData(af_Object *obj, int **data, af_Environment *env) {
     *data = calloc(sizeof(int), 1);
     *data = calloc(sizeof(int), 1);
     **data = 100;
     **data = 100;
 }
 }
 
 
-void freeData(char *id, int **data, af_Environment *env) {
+void freeData(af_Object *obj, int **data, af_Environment *env) {
     printf("freeData(): **data = %d\n", **data);
     printf("freeData(): **data = %d\n", **data);
     free(*data);
     free(*data);
 }
 }
 
 
-size_t getSize2(char *id) {
+size_t getSize2(af_Object *obj) {
     return sizeof(af_VarSpaceListNode *);
     return sizeof(af_VarSpaceListNode *);
 }
 }
 
 
-void initData2(char *id, af_VarSpaceListNode **data, af_Environment *env) {
+void initData2(af_Object *obj, af_VarSpaceListNode **data, af_Environment *env) {
     *data = makeVarSpaceList(getProtectVarSpace(env));
     *data = makeVarSpaceList(getProtectVarSpace(env));
 }
 }
 
 
-void freeData2(char *id, af_VarSpaceListNode **data, af_Environment *env) {
+void freeData2(af_Object *obj, af_VarSpaceListNode **data, af_Environment *env) {
     printf("freeData2(): vsl = %p\n", *data);
     printf("freeData2(): vsl = %p\n", *data);
     freeAllVarSpaceList(*data);
     freeAllVarSpaceList(*data);
 }
 }
 
 
-size_t getSize3(char *id) {
+size_t getSize3(af_Object *obj) {
     return sizeof(af_VarSpace *);
     return sizeof(af_VarSpace *);
 }
 }
 
 
-void initData3(char *id, af_VarSpace **data, af_Environment *env) {
-    *data = makeVarSpace(env);
+void initData3(af_Object *obj, af_VarSpace **data, af_Environment *env) {
+    *data = makeVarSpace(obj, env);
 }
 }
 
 
-void freeData3(char *id, af_VarSpace **data, af_Environment *env) {
+void freeData3(af_Object *obj, af_VarSpace **data, af_Environment *env) {
     printf("freeData(): *data = %p\n", *data);
     printf("freeData(): *data = %p\n", *data);
     freeVarSpace(*data, env);
     freeVarSpace(*data, env);
 }
 }
@@ -294,7 +294,7 @@ af_FuncBody *testFunc6(int *mark, af_Environment *env) {  // 测试用函数
         FREE_SYMBOL(freeData_2);
         FREE_SYMBOL(freeData_2);
     }
     }
 
 
-    setObjectAttributes(gc_destruct, 3, 3, des, obj, env);
+    setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, env);
     pushMessageDown(makeNORMALMessage(obj), env);
     pushMessageDown(makeNORMALMessage(obj), env);
     printf("testFunc6[des](%p, %p): I am testFunc6\n", obj, des);
     printf("testFunc6[des](%p, %p): I am testFunc6\n", obj, des);
     return NULL;
     return NULL;
@@ -346,7 +346,7 @@ af_FuncBody *testFunc5(int *mark, af_Environment *env) {  // 测试用函数
         FREE_SYMBOL(freeData_2);
         FREE_SYMBOL(freeData_2);
     }
     }
 
 
-    setObjectAttributes(gc_destruct, 3, 3, des, obj, env);
+    setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, env);
     pushMessageDown(makeNORMALMessage(obj), env);
     pushMessageDown(makeNORMALMessage(obj), env);
     printf("testFunc5(%p, %p): I am testFunc5\n", obj, des);
     printf("testFunc5(%p, %p): I am testFunc5\n", obj, des);
     return NULL;
     return NULL;
@@ -383,7 +383,7 @@ int main() {
         if (addAPI(freeData_, "obj_destructData", api) != 1)
         if (addAPI(freeData_, "obj_destructData", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("global", 3, 3,
+        addVarToProtectVarSpace(makeVar("global", 3, 3, 3,
                                         (obj = makeObject("global", true, api, true, NULL, NULL, env)), env),
                                         (obj = makeObject("global", true, api, true, NULL, NULL, env)), env),
                                 env);
                                 env);
         FREE_SYMBOL(getSize_);
         FREE_SYMBOL(getSize_);
@@ -411,7 +411,7 @@ int main() {
         if (addAPI(get_gl3, "obj_getGcList", api) != 1)
         if (addAPI(get_gl3, "obj_getGcList", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("object", 3, 3,
+        addVarToProtectVarSpace(makeVar("object", 3, 3, 3,
                                         (obj = makeObject("object", true, api, true, NULL, NULL, env)),
                                         (obj = makeObject("object", true, api, true, NULL, NULL, env)),
                                         env),
                                         env),
                                 env);
                                 env);
@@ -454,7 +454,7 @@ int main() {
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("func", 3, 3,
+        addVarToProtectVarSpace(makeVar("func", 3, 3, 3,
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                 env);
                                 env);
         FREE_SYMBOL(get_alc);
         FREE_SYMBOL(get_alc);
@@ -500,7 +500,7 @@ int main() {
         if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
         if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("func2", 3, 3,
+        addVarToProtectVarSpace(makeVar("func2", 3, 3, 3,
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                 env);
                                 env);
         FREE_SYMBOL(get_alc);
         FREE_SYMBOL(get_alc);
@@ -546,7 +546,7 @@ int main() {
         if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
         if (addAPI(free_mark, "obj_funcFreeMask", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("func3", 3, 3,
+        addVarToProtectVarSpace(makeVar("func3", 3, 3, 3,
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                 env);
                                 env);
         FREE_SYMBOL(get_alc);
         FREE_SYMBOL(get_alc);
@@ -595,7 +595,7 @@ int main() {
         if (addAPI(obj_func, "obj_isObjFunc", api) != 1)
         if (addAPI(obj_func, "obj_isObjFunc", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("func4", 3, 3,
+        addVarToProtectVarSpace(makeVar("func4", 3, 3, 3,
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                 env);
                                 env);
         FREE_SYMBOL(get_alc);
         FREE_SYMBOL(get_alc);
@@ -642,7 +642,7 @@ int main() {
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("func5", 3, 3,
+        addVarToProtectVarSpace(makeVar("func5", 3, 3, 3,
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                 env);
                                 env);
         FREE_SYMBOL(get_alc);
         FREE_SYMBOL(get_alc);
@@ -690,8 +690,8 @@ int main() {
             FREE_SYMBOL(freeData_2);
             FREE_SYMBOL(freeData_2);
         }
         }
 
 
-        setObjectAttributes(gc_destruct, 3, 3, des, obj, env);
-        addVarToProtectVarSpace(makeVar("func6", 3, 3, obj, env), env);
+        setObjectAttributes(gc_destruct, 3, 3, 3, des, obj, env);
+        addVarToProtectVarSpace(makeVar("func6", 3, 3, 3, obj, env), env);
         printf("func6(%p)\n", obj);
         printf("func6(%p)\n", obj);
     }
     }
 
 
@@ -726,7 +726,7 @@ int main() {
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
         if (addAPI(get_gl, "obj_getGcList", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("func7", 3, 3,
+        addVarToProtectVarSpace(makeVar("func7", 3, 3, 3,
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                         (obj = makeObject("func", true, api, true, NULL, NULL, env)), env),
                                 env);
                                 env);
         FREE_SYMBOL(get_alc);
         FREE_SYMBOL(get_alc);

+ 10 - 10
test/test_env.c

@@ -1,29 +1,29 @@
 #include <stdio.h>
 #include <stdio.h>
 #include "aFun.h"
 #include "aFun.h"
 
 
-size_t getSize(void) {
+size_t getSize(af_Object *obj) {
     return sizeof(int *);
     return sizeof(int *);
 }
 }
 
 
-void initData(int **data) {
+void initData(af_Object *obj, int **data, af_Environment *env) {
     *data = calloc(sizeof(int), 1);
     *data = calloc(sizeof(int), 1);
     **data = 100;
     **data = 100;
 }
 }
 
 
-void freeData(int **data) {
-    printf("**data = %d\n", **data);
+void freeData(af_Object *obj, int **data, af_Environment *env) {
+    printf("freeData(): **data = %d\n", **data);
     free(*data);
     free(*data);
 }
 }
 
 
-size_t getSize3(char *id) {
+size_t getSize3(af_Object *obj) {
     return sizeof(af_VarSpace *);
     return sizeof(af_VarSpace *);
 }
 }
 
 
-void initData3(char *id, af_VarSpace **data, af_Environment *env) {
-    *data = makeVarSpace(env);
+void initData3(af_Object *obj, af_VarSpace **data, af_Environment *env) {
+    *data = makeVarSpace(obj, env);
 }
 }
 
 
-void freeData3(char *id, af_VarSpace **data, af_Environment *env) {
+void freeData3(af_Object *obj, af_VarSpace **data, af_Environment *env) {
     printf("freeData(): *data = %p\n", *data);
     printf("freeData(): *data = %p\n", *data);
     freeVarSpace(*data, env);
     freeVarSpace(*data, env);
 }
 }
@@ -54,7 +54,7 @@ int main() {
         if (addAPI(freeData_, "obj_destructData", api) != 1)
         if (addAPI(freeData_, "obj_destructData", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("global", 3, 3,
+        addVarToProtectVarSpace(makeVar("global", 3, 3, 3,
                                         makeObject("global", true, api, true, NULL, NULL, env), env),
                                         makeObject("global", true, api, true, NULL, NULL, env), env),
                                 env);
                                 env);
         FREE_SYMBOL(getSize_);
         FREE_SYMBOL(getSize_);
@@ -80,7 +80,7 @@ int main() {
         if (addAPI(get_gl3, "obj_getGcList", api) != 1)
         if (addAPI(get_gl3, "obj_getGcList", api) != 1)
             return 2;
             return 2;
 
 
-        addVarToProtectVarSpace(makeVar("object", 3, 3,
+        addVarToProtectVarSpace(makeVar("object", 3, 3, 3,
                                         makeObject("object", true, api, true, NULL, NULL, env),
                                         makeObject("object", true, api, true, NULL, NULL, env),
                                         env),
                                         env),
                                 env);
                                 env);