Baby’s First Garbage Collector › 一对对象 A pair of objects [#266]

在我们开始实现这两个步骤之前,让我们先做一些准备工作。我们不会真正实现一种语言的解释器⸺没有语法分析器、字节码或任何弱智的东西⸺但我们确实需要一些最少量的代码来创建一些垃圾来回收。
Before we can get to implementing those two steps, let’s get a couple of preliminaries out of the way. We won’t be actually implementing an interpreter for a language—no parser, bytecode, or any of that foolishness—but we do need some minimal amount of code to create some garbage to collect.

假设我们正在为一种小语言编写一个解释器。它是动态类型的,有两种类型的对象:整数(int)和对(pair)。这是一个用来标记对象类型的枚举:
Let’s play pretend that we’re writing an interpreter for a little language. It’s dynamically typed, and has two types of objects: ints and pairs. Here’s an enum to identify an object’s type:

typedef enum {
  OBJ_INT,
  OBJ_PAIR
} ObjectType;

一个对可以是一对任何东西,两个整数,一个整数和另一个对,等等。仅凭这一点,你就可以走得更远。由于 VM 中的对象可以是其中任何一个,因此 C 中实现它的典型方法是使用标签联合(tagged union)。我们这样定义它:
A pair can be a pair of anything, two ints, an int and another pair, whatever. You can go surprisingly far (http://www.flickr.com/photos/raganwald/212588975/) with just that. Since an object in the VM can be either of these, the typical way in C to implement it is with a tagged union (http://en.wikipedia.org/wiki/Tagged_union). We define it thusly:

typedef struct sObject {
  ObjectType type;

  union {
    /* OBJ_INT */
    int value;

    /* OBJ_PAIR */
    struct {
      struct sObject* head;
      struct sObject* tail;
    };
  };
} Object;

主要的 Object 结构中有一个 type 字段,用于标识它的值类型⸺整数或对。接着它有一个联合(union)来保存这个整数或对的数据。如果你的 C 很生疏,那么联合就是一个结构体,其中字段在内存中重叠。由于给定的对象只能是一个整数一个对,因此没有理由在单个对象中同时为所有三个字段提供内存。联合就是这么做的。非常好。
The main Object struct has a type field that identifies what kind of value it is—either an int or a pair. Then it has a union to hold the data for the int or pair. If your C is rusty, a union is a struct where the fields overlap in memory. Since a given object can only be an int or a pair, there’s no reason to have memory in a single object for all three fields at the same time. A union does that. Groovy.