1.1.2 头字段的其它部分

Keywords:

Next: ,Previous: SEXPTYPEs,Up: SEXPs

1.1.2 头字段的其它部分

头字段 sxpinfo 是以如下的 32 位 C 结构定义

     struct sxpinfo_struct {

         SEXPTYPE type      :  5;  /* 上面已经讨论过 */

         unsigned int obj   :  1;  /* 这是一个有类属性的对象吗? */

         unsigned int named :  2;  /* 用于控制拷贝 */

         unsigned int gp    : 16;  /* 通常目的,见下面的内容 */

         unsigned int mark  :  1;  /* 在GC里面标识 `in use'(在使用) */

         unsigned int debug :  1;

         unsigned int trace :  1;

         unsigned int spare :  1;  /* 没有被使用的 */

         unsigned int gcgen :  1;  /* GC的世代数 */

         unsigned int gccls :  3;  /* GC的节点的类 */

     };  /*              Tot: 32 */

debug 位用于闭包(closures)和环境(environments)。对于闭包, 通过 debug() 载入和 undebug() 卸载,并且表明函数的求值 必须在浏览器下运行1。对于环境,它只表明浏览器是否处于单步模式(single-step mode)。

trace 位用于进行 trace() (代码跟踪测试)的函数,并且用于副本跟踪测试(见 tracemem)的其它对象。

named 字段通过 SET_NAMEDNAMED 宏设置和访问。它的值可能是 012。R 有`值传递'(call by value)的假象,因此类似下面的赋值操作

     b <- a

看上去是拷贝一份 a 然后用 b 去访问。但是,如果ab 随后都没有改变,则没有必要把它拷贝一份。实际情况是,新符号 ba 绑定一样的值,并且 对值对象(value object)的 named 字段进行设置(在这种情况下设为 2)。当一个对象要改变时,要参考 named 字段的值。该字段是 2 意味着这个对象在改变之前需要复制一下。(注意,这并没有要求该对象一定要复制一下,仅仅表示它需要复制一下无论是否真的需要)。字段值是0 时表示没有其它 SEXP 和这个对象共享数据,因此对它的修改是安全的。字段值是 1 用于如下情况

     dim(a) <- c(7, 2)

其中,a 在整个计算过程中原则上以两份拷贝的形式存在,大体上如下所示2

     a <- `dim<-`(a, c(7, 2))

但是在这种情况下,这种多拷贝的形式不再是必要的,如一些原始函数可以通过优化来避免额外的一份拷贝。

gp 位用`通用目的'(`general purpose')来定义。 从 R 2.4.0 开始,位 4(即,第五位)用于标明 S4 对象。位 0-3 和 位 14-15 之前已经被使用,下面会详细描述(通过源码的细致分析说明)。

这些位变量可以通过 LEVELSSETLEVELS 宏访问或设置。这两个宏的名字看上去和内部因子和有序因子类型有关,但现在已很少在代码里面出现了。gp 字段是对 SEXPTYPE 类型是串行化的/非串行化的(serialized/unserialized),而对 NILSXPSYMSXPENVSXP则不是。

如果我们为从0开始的位分类,gp 的位14和15用于`特异绑定'(`fancy bindings')。位14用锁定一个绑定或环境,而位15用于表明一个处于活动状态的绑定。(对于`活动状态的绑定'(`active binding')的定义见源码文件 src/main/envir.c 的头注释部分。位15用于表明一个环境是否参与全局高速缓存(global cache)。

几乎所有其它使用仅仅使用位0和1,尽管它们科研保留开始的4个位。

ARGUSEDSET_ARGUSED 在匹配事实和形式函数参数的时候使用。它可能的取值是 0, 1 和 2。

MISSINGSET_MISSING 用于参数的成对列表。4个位被保留,但只有两个可以使用(具体为什么会这样,现在还没有解释)。似乎,位0被 matchArgs 用于标记返回参数列表中的缺失的参数,位1用来标记把默认值拷贝给闭包求值框架的某个参数。

DDVALSET_DDVAL 使用位0。这表明 SYMSXP 是当 ... 被处理时,默认创建的 ..n 符号的一种。同时也表明,该位可能需要在 DOTSXP 查询。

位 0 用于标签 PRSEEN。该标签表明一个允诺(promise)在允诺求值过程中是否可见(这样可以避免递归回路(recursive loops))。

在环境框架下TAGPRINTNAME 上面,位 0 用于 HASHASH

位 0 和 1 用于弱引用(weak references)(用于表明`准备终结'('ready to finalize'),`退出时终结'('finalize on exit'))。

位 0 用在条件处理系统(condition handling system)(利用VECSXP)时来表明一个调用处理器(calling handler)。

从 R 2.5.0 开始,CHARSXP的位 2 和 3 分布用于表示大家熟知的 Latin-1 和 UTF-8 字符编码。(如果是ASCII,则不需要设置。因为代码在处理ASCII字符串的时候没有必要知道字符编码)。


Footnotes

[1] 译者注:原句为“ Forclosures it is set by debug() and unset by undebug(), andindicates that evaluations of the function should be run under thebrowser.”

[2] 译者注:事实上以函数的形式表示,见《R语言定义》

Hits:Loading...

special topic