# 对象管理器文档

对象管理器的主要文件是src/data_type目录下的Variable.cpp和src/vm目录下的ObjectManager.cpp。

其中，ObjectManager.cpp基于Variable.cpp。

### 数据结构

``Variable``是一个非常简单的类，它有一个名为```data```的```DataType*```成员，所以对于任意左值，我们只需要得到这个左值的```Variable*```值，就可以对这个左值进行赋值（而不需要知道这个左值的具体信息）。

比如，对于一个名为```var```的```Variable*```对象和一个名为```dat```的```DataType*```对象，想要把```var```（也就是左值）赋值为```dat```（也就是右值），只需要这么做：

```C++
var->data = dat;
```

**换句话说，每个左值都对应着一个```Variable*```对象，而可以通过给这个对象的data成员赋值，从而达到给该左值赋值的目的**

### 核心原理

``ObjectManager.cpp``编写了对象管理器的本体。对象管理器包含了GC机制以及作用域管理功能。虚拟机的对象应向对象管理器申请。

GC所采用的算法是**标记-清除法**。我用一个栈来维护运行时所有的作用域。新建或退出一个作用域时只需要入栈或出栈即可。寻找某个变量也只需要从栈顶找到栈底就行。

以下是ObjectManager.cpp的核心接口：

##### 对象管理接口

|函数原型|解释|
|:-|:-|
|``ObjectManager(bool isGC, unsigned long long mem_limit, int pool_cache_size, STMException* e)``|``isGC``代表对象管理器是否执行GC，若执行GC，则``mem_limit``有意义，且代表GC的内存限制，若不执行GC，则对象管理器会一直运行直到内存溢出。pool_cache_size代表内存池的缓存大小。对pool_cache_size的具体解释应看``MemoryPool.hpp``的实现|
|``datatype::NullType* getNullConst()``|获取``null``常量|
|``template<class T> bool GCConditions(T* object)``|新建对象后，对象管理器会把这个对象交给``GCConditions``函数，根据函数返回判断是否需要GC。该函数可交给开发者自定义。虚拟机默认的条件为：对象占用内存+GC预留内存大等于内存限制时。|
|``void GC()``|执行GC|
|``template<class T, typename...Types> T* MallocObject(Types&& ...args)``|申请一个对象，需要提供申请的对象类型和初始化参数，例如``MallocObject<IntegerType>(1)``代表申请一个类型为整数，值为1的对象|

##### 作用域管理

|函数原型|解释|
|:-|:-|
|``Variable* NewVariable(int id)``|新建一个变量，默认为空值|
|``Variable* NewVariable(int id, datatype::DataType* val)``|新建一个变量，并赋值为``val``|
|``Variable* getVariable(int id)``|获取变量的值|
|``void pushScope()``|压入一个空作用域|
|``void popScope()``|**销毁并弹出**一个作用域|
|``void pushMemberTabScope(ObjectScope s)``|压入一个指定为``s``的作用域，一般用于类对象初始化时|
|``void popMemberTabScope()``|弹出一个作用域**但不销毁**，一般用于类对象初始化时|
|``ObjectScope getTopScope()``|获取栈顶的作用域|