1、前言
在erlang数据类型的c源码解析(1)-Eterm讲到,当Eterm的低2位为10B时,为Boxed(装箱)类型。tuple是Boxed类型中的一种。
低2位外的位数用来表示一个指向arityval的指针。
arityval的定义如下如下:
// _TAG_PRIMARY_SIZE = 2
// 主标签占2位,子标签占4位,所以arityval的低6位是000000B
#define ARITYVAL_SUBTAG (0x0 << _TAG_PRIMARY_SIZE) /* TUPLE */
为arityval是一块连续内存空间,可以当作是C语言的数组,且数组首部元素为数组的长度。
结构如下图:
(图片来源:https://blog.edfine.io/blog/2016/06/28/erlang-data-representation/ , 侵删)
2、宏定义(erl_term.h)
// make_tuple最终会调用到_unchecked_make_boxed,其实就是将Eterm低2位设成10B
#define make_tuple(x) make_boxed((x))
#define _unchecked_make_boxed(x) ((Uint) COMPRESS_POINTER(x) + TAG_PRIMARY_BOXED)
_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*)
#define make_boxed(x) _ET_APPLY(make_boxed,(x))
// _TAG_HEADER_ARITYVAL = 0
// make_arityval实质上是将sz左移6位,保证低6位为000000B
// 使其满足PrimaryTag为HEADER,SubTag为ARITYVAL
#define make_arityval(sz) _make_header((sz),_TAG_HEADER_ARITYVAL)
#define _make_header(sz,tag) ((Uint)(((sz) << _HEADER_ARITY_OFFS) + (tag)))
#define _HEADER_ARITY_OFFS 6