📄 erl_term.h
字号:
* +--------------+--------------+ * | Thing word | * +--------------+--------------+ * | Data 0 | 32-bit arity | * +--------------+--------------+ * | Data 2 | Data 1 | * +--------------+--------------+ * * Data is stored as an Uint32 array with 32-bit arity as first number. */#define write_ref_thing(Hp, R0, R1, R2) \do { \ ((RefThing *) (Hp))->header = make_ref_thing_header(ERTS_REF_WORDS); \ ((Uint32 *) ((RefThing *) (Hp))->data)[0] = ERTS_REF_NUMBERS; \ ((Uint32 *) ((RefThing *) (Hp))->data)[1] = (R0); \ ((Uint32 *) ((RefThing *) (Hp))->data)[2] = (R1); \ ((Uint32 *) ((RefThing *) (Hp))->data)[3] = (R2); \} while (0)#else#define write_ref_thing(Hp, R0, R1, R2) \do { \ ((RefThing *) (Hp))->header = make_ref_thing_header(ERTS_REF_WORDS); \ ((Uint32 *) ((RefThing *) (Hp))->data)[0] = (R0); \ ((Uint32 *) ((RefThing *) (Hp))->data)[1] = (R1); \ ((Uint32 *) ((RefThing *) (Hp))->data)[2] = (R2); \} while (0)#endif#define is_ref_thing_header(x) (((x) & _TAG_HEADER_MASK) == _TAG_HEADER_REF)#define make_internal_ref(x) make_boxed((Eterm*)(x))#define _unchecked_ref_thing_ptr(x) \ ((RefThing*) _unchecked_internal_ref_val(x))#define ref_thing_ptr(x) \ ((RefThing*) internal_ref_val(x))#define is_internal_ref(x) \ (_unchecked_is_boxed((x)) && is_ref_thing_header(*boxed_val((x))))#define is_not_internal_ref(x) \ (!is_internal_ref((x)))#define _unchecked_internal_ref_val(x) _unchecked_boxed_val((x))_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Eterm);#define internal_ref_val(x) _ET_APPLY(internal_ref_val,(x))#define _unchecked_internal_ref_data_words(x) \ (_unchecked_thing_arityval(*_unchecked_internal_ref_val(x)))_ET_DECLARE_CHECKED(Uint,internal_ref_data_words,Eterm);#define internal_ref_data_words(x) _ET_APPLY(internal_ref_data_words,(x))#define _unchecked_internal_ref_data(x) (_unchecked_ref_thing_ptr(x)->data)_ET_DECLARE_CHECKED(Uint*,internal_ref_data,Eterm);#define internal_ref_data(x) _ET_APPLY(internal_ref_data,(x))#define _unchecked_internal_ref_node(x) erts_this_node_ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm);#define internal_ref_node(x) _ET_APPLY(internal_ref_node,(x))/* * * External thing layout (external pids, ports, and refs): * * |3 3 2 2 2 2 2 2|2 2 2 2 1 1 1 1|1 1 1 1 1 1 | | * |1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0| * | | | | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |A A A A A A A A A A A A A A A A A A A A A A A A A A|t t t t|0 0| Thing * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N N| Next * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E E| ErlNode * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * |X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X| Data 0 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * . . . * . . . * . . . * * A : Arity * t : External pid thing tag (1100) * t : External port thing tag (1101) * t : External ref thing tag (1110) * N : Next (external thing) pointer * E : ErlNode pointer * X : Type specific data * * External pid and port layout: * External pids and ports only have one data word (Data 0) which has * the same layout as internal pids resp. internal ports. * * External refs layout: * External refs has the same layout for the data words as in the internal * ref. * */typedef struct external_thing_ { /* ----+ */ Eterm header; /* | */ struct external_thing_ *next; /* > External thing head */ struct erl_node_ *node; /* | */ /* ----+ */ Uint data[1];} ExternalThing;#define EXTERNAL_THING_HEAD_SIZE (sizeof(ExternalThing)/sizeof(Uint) - 1)#define make_external_pid_header(DW) \ _make_header((DW)+EXTERNAL_THING_HEAD_SIZE-1,_TAG_HEADER_EXTERNAL_PID)#define is_external_pid_header(x) \ (((x) & _TAG_HEADER_MASK) == _TAG_HEADER_EXTERNAL_PID)#define make_external_port_header(DW) \ _make_header((DW)+EXTERNAL_THING_HEAD_SIZE-1,_TAG_HEADER_EXTERNAL_PORT)#define is_external_port_header(x) \ (((x) & _TAG_HEADER_MASK) == _TAG_HEADER_EXTERNAL_PORT)#define make_external_ref_header(DW) \ _make_header((DW)+EXTERNAL_THING_HEAD_SIZE-1,_TAG_HEADER_EXTERNAL_REF)#define is_external_ref_header(x) \ (((x) & _TAG_HEADER_MASK) == _TAG_HEADER_EXTERNAL_REF)#define is_external_header(x) \ (((x) & (_TAG_HEADER_MASK-_BINARY_XXX_MASK)) == _TAG_HEADER_EXTERNAL_PID)#define is_external(x) \ (is_boxed((x)) && is_external_header(*boxed_val((x))))#define is_external_pid(x) \ (is_boxed((x)) && is_external_pid_header(*boxed_val((x))))#define is_external_port(x) \ (is_boxed((x)) && is_external_port_header(*boxed_val((x))))#define is_external_ref(x) \ (_unchecked_is_boxed((x)) && is_external_ref_header(*boxed_val((x))))#define _unchecked_is_external(x) \ (_unchecked_is_boxed((x)) && is_external_header(*_unchecked_boxed_val((x))))#define is_not_external(x) (!is_external((x)))#define is_not_external_pid(x) (!is_external_pid((x)))#define is_not_external_port(x) (!is_external_port((x)))#define is_not_external_ref(x) (!is_external_ref((x)))#define make_external(x) make_boxed((Eterm *) (x))#define make_external_pid make_external#define make_external_port make_external#define make_external_ref make_external#define _unchecked_external_val(x) _unchecked_boxed_val((x))_ET_DECLARE_CHECKED(Eterm*,external_val,Eterm);#define external_val(x) _ET_APPLY(external_val,(x))#define external_thing_ptr(x) ((ExternalThing *) external_val((x)))#define _unchecked_external_thing_ptr(x) \ ((ExternalThing *) _unchecked_external_val((x)))#define _unchecked_external_data_words(x) \ (_unchecked_thing_arityval(_unchecked_external_thing_ptr((x))->header) \ + (1 - EXTERNAL_THING_HEAD_SIZE))_ET_DECLARE_CHECKED(Uint,external_data_words,Eterm);#define external_data_words(x) _ET_APPLY(external_data_words,(x))#define _unchecked_external_data(x) (_unchecked_external_thing_ptr((x))->data)#define _unchecked_external_node(x) (_unchecked_external_thing_ptr((x))->node)#define external_data(x) (external_thing_ptr((x))->data)#define external_node(x) (external_thing_ptr((x))->node)#define _unchecked_external_pid_data_words(x) \ _unchecked_external_data_words((x))_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Eterm);#define external_pid_data_words(x) _ET_APPLY(external_pid_data_words,(x))#define _unchecked_external_pid_data(x) _unchecked_external_data((x))[0]_ET_DECLARE_CHECKED(Uint,external_pid_data,Eterm);#define external_pid_data(x) _ET_APPLY(external_pid_data,(x))#define _unchecked_external_pid_node(x) _unchecked_external_node((x))_ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm);#define external_pid_node(x) _ET_APPLY(external_pid_node,(x))#define external_pid_number(x) _GET_PID_NUM(external_pid_data((x)))#define external_pid_serial(x) _GET_PID_SER(external_pid_data((x)))#define _unchecked_external_port_data_words(x) \ _unchecked_external_data_words((x))_ET_DECLARE_CHECKED(Uint,external_port_data_words,Eterm);#define external_port_data_words(x) _ET_APPLY(external_port_data_words,(x))#define _unchecked_external_port_data(x) _unchecked_external_data((x))[0]_ET_DECLARE_CHECKED(Uint,external_port_data,Eterm);#define external_port_data(x) _ET_APPLY(external_port_data,(x))#define _unchecked_external_port_node(x) _unchecked_external_node((x))_ET_DECLARE_CHECKED(struct erl_node_*,external_port_node,Eterm);#define external_port_node(x) _ET_APPLY(external_port_node,(x))#define external_port_number(x) _GET_PORT_NUM(external_port_data((x)))#define _unchecked_external_ref_data_words(x) \ _unchecked_external_data_words((x))_ET_DECLARE_CHECKED(Uint,external_ref_data_words,Eterm);#define external_ref_data_words(x) _ET_APPLY(external_ref_data_words,(x))#define _unchecked_external_ref_data(x) _unchecked_external_data((x))_ET_DECLARE_CHECKED(Uint*,external_ref_data,Eterm);#define external_ref_data(x) _ET_APPLY(external_ref_data,(x))#define _unchecked_external_ref_node(x) _unchecked_external_node((x))_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm);#define external_ref_node(x) _ET_APPLY(external_ref_node,(x))/* number tests */#define is_integer(x) (is_small(x) || is_big(x))#define is_not_integer(x) (!is_integer(x))#define is_number(x) (is_integer(x) || is_float(x))#define SMALL_MINUS_ONE make_small(-1)#define SMALL_ZERO make_small(0)#define SMALL_ONE make_small(1)#define ENULL 0/* on some architectures CP contains labels which are not aligned */#ifdef NOT_ALIGNED#error "fix yer arch, like"#endif#define _unchecked_make_cp(x) ((Eterm)(x))_ET_DECLARE_CHECKED(Eterm,make_cp,Uint*);#define make_cp(x) _ET_APPLY(make_cp,(x))#define is_not_CP(x) ((x) & _CPMASK)#define is_CP(x) (!is_not_CP(x))#define _unchecked_cp_val(x) ((Uint*)(x))_ET_DECLARE_CHECKED(Uint*,cp_val,Eterm);#define cp_val(x) _ET_APPLY(cp_val,(x))#define make_catch(x) (((x) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_CATCH)#define is_catch(x) (((x) & _TAG_IMMED2_MASK) == _TAG_IMMED2_CATCH)#define is_not_catch(x) (!is_catch(x))#define _unchecked_catch_val(x) ((x) >> _TAG_IMMED2_SIZE)_ET_DECLARE_CHECKED(Uint,catch_val,Eterm);#define catch_val(x) _ET_APPLY(catch_val,(x))#define make_blank(X) ((X) = NIL)/* * Overloaded tags. * * SMALL = 15 * ATOM/NIL=7 * * Note that the two least significant bits in SMALL/ATOM/NIL always are 3; * thus, we can distinguish register from literals by looking at only these * two bits. */#define X_REG_DEF 0#define Y_REG_DEF 1#define R_REG_DEF 2#define beam_reg_tag(x) ((x) & 3)#define make_rreg() R_REG_DEF#define make_xreg(ix) (((ix) * sizeof(Eterm)) | X_REG_DEF)#define make_yreg(ix) (((ix) * sizeof(Eterm)) | Y_REG_DEF)#define _is_xreg(x) (beam_reg_tag(x) == X_REG_DEF)#define _is_yreg(x) (beam_reg_tag(x) == Y_REG_DEF)#define _unchecked_x_reg_offset(R) ((R) - X_REG_DEF)_ET_DECLARE_CHECKED(Uint,x_reg_offset,Uint);#define x_reg_offset(R) _ET_APPLY(x_reg_offset,(R))#define _unchecked_y_reg_offset(R) ((R) - Y_REG_DEF)_ET_DECLARE_CHECKED(Uint,y_reg_offset,Uint);#define y_reg_offset(R) _ET_APPLY(y_reg_offset,(R))#define reg_index(R) ((R) / sizeof(Eterm))#define _unchecked_x_reg_index(R) ((R) >> 2)_ET_DECLARE_CHECKED(Uint,x_reg_index,Uint);#define x_reg_index(R) _ET_APPLY(x_reg_index,(R))#define _unchecked_y_reg_index(R) ((R) >> 2)_ET_DECLARE_CHECKED(Uint,y_reg_index,Uint);#define y_reg_index(R) _ET_APPLY(y_reg_index,(R))/* * Backwards compatibility definitions: * - #define virtal *_DEF constants with values that fit term order: * number < atom < ref < fun < port < pid < tuple < nil < cons < binary * - tag_val_def() function generates virtual _DEF tag * - not_eq_tags() and NUMBER_CODE() defined in terms * of the tag_val_def() function */#define BINARY_DEF 0x0#define LIST_DEF 0x1#define NIL_DEF 0x2#define TUPLE_DEF 0x3#define PID_DEF 0x4#define EXTERNAL_PID_DEF 0x5#define PORT_DEF 0x6#define EXTERNAL_PORT_DEF 0x7#define EXPORT_DEF 0x8#define FUN_DEF 0x9#define REF_DEF 0xa#define EXTERNAL_REF_DEF 0xb#define ATOM_DEF 0xc#define FLOAT_DEF 0xd#define BIG_DEF 0xe#define SMALL_DEF 0xf#if ET_DEBUGextern unsigned tag_val_def_debug(Eterm, const char*, unsigned);#define tag_val_def(x) tag_val_def_debug((x),__FILE__,__LINE__)#elseextern unsigned tag_val_def(Eterm);#endif#define not_eq_tags(X,Y) (tag_val_def((X)) ^ tag_val_def((Y)))#define NUMBER_CODE(x,y) ((tag_val_def(x) << 4) | tag_val_def(y))#define _NUMBER_CODE(TX,TY) ((TX << 4) | TY)#define SMALL_SMALL _NUMBER_CODE(SMALL_DEF,SMALL_DEF)#define SMALL_BIG _NUMBER_CODE(SMALL_DEF,BIG_DEF)#define SMALL_FLOAT _NUMBER_CODE(SMALL_DEF,FLOAT_DEF)#define BIG_SMALL _NUMBER_CODE(BIG_DEF,SMALL_DEF)#define BIG_BIG _NUMBER_CODE(BIG_DEF,BIG_DEF)#define BIG_FLOAT _NUMBER_CODE(BIG_DEF,FLOAT_DEF)#define FLOAT_SMALL _NUMBER_CODE(FLOAT_DEF,SMALL_DEF)#define FLOAT_BIG _NUMBER_CODE(FLOAT_DEF,BIG_DEF)#define FLOAT_FLOAT _NUMBER_CODE(FLOAT_DEF,FLOAT_DEF)#endif /* __ERL_TERM_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -