⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_term.h

📁 OTP是开放电信平台的简称
💻 H
📖 第 1 页 / 共 3 页
字号:
/* ``The contents of this file are subject to the Erlang Public License, * Version 1.1, (the "License"); you may not use this file except in * compliance with the License. You should have received a copy of the * Erlang Public License along with this software. If not, it can be * retrieved via the world wide web at http://www.erlang.org/. *  * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ */#ifndef __ERL_TERM_H#define __ERL_TERM_Hstruct erl_node_; /* Declared in erl_node_tables.h *//* * Defining ET_DEBUG to 1 causes all type-specific data access * macros to perform runtime type checking. This is very useful * during development but reduces performance, so ET_DEBUG should * be disabled during benchmarking or release. *//* #define ET_DEBUG 1 */#ifndef ET_DEBUG#  ifdef DEBUG#    define ET_DEBUG 1#  else#    define ET_DEBUG 0#  endif#endif#if ET_DEBUG#define _ET_DECLARE_CHECKED(TF,F,TX) extern TF checked_##F(TX,const char*,unsigned)#define _ET_APPLY(F,X)	checked_##F(X,__FILE__,__LINE__)#else#define _ET_DECLARE_CHECKED(TF,F,TX)#define _ET_APPLY(F,X)	_unchecked_##F(X)#endif#define _TAG_PRIMARY_SIZE	2#define _TAG_PRIMARY_MASK	0x3#define TAG_PRIMARY_HEADER	0x0#define TAG_PRIMARY_LIST	0x1#define TAG_PRIMARY_BOXED	0x2#define TAG_PRIMARY_IMMED1	0x3#define primary_tag(x)	((x) & _TAG_PRIMARY_MASK)#define _TAG_IMMED1_SIZE	4#define _TAG_IMMED1_MASK	0xF#define _TAG_IMMED1_PID		((0x0 << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_IMMED1)#define _TAG_IMMED1_PORT	((0x1 << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_IMMED1)#define _TAG_IMMED1_IMMED2	((0x2 << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_IMMED1)#define _TAG_IMMED1_SMALL	((0x3 << _TAG_PRIMARY_SIZE) | TAG_PRIMARY_IMMED1)#define _TAG_IMMED2_SIZE	6#define _TAG_IMMED2_MASK	0x3F#define _TAG_IMMED2_ATOM	((0x0 << _TAG_IMMED1_SIZE) | _TAG_IMMED1_IMMED2)#define _TAG_IMMED2_CATCH	((0x1 << _TAG_IMMED1_SIZE) | _TAG_IMMED1_IMMED2)#define _TAG_IMMED2_NIL		((0x3 << _TAG_IMMED1_SIZE) | _TAG_IMMED1_IMMED2)/* * HEADER representation: * *	aaaaaaaaaaaaaaaaaaaaaaaaaatttt00	arity:26, tag:4 * * HEADER tags: * *	0000	ARITYVAL *      0001    BINARY_AGGREGATE                | *	001x	BIGNUM with sign bit		| *	0100	REF				| *	0101	FUN				| THINGS *	0110	FLONUM				| *      0111    EXPORT                          | *	1000	REFC_BINARY	|		| *	1001	HEAP_BINARY	| BINARIES	| *	1010	SUB_BINARY	|		| *      1011    Not used *      1100    EXTERNAL_PID  |                 | *      1101    EXTERNAL_PORT | EXTERNAL THINGS | *      1110    EXTERNAL_REF  |                 | *      1111    Not used * * COMMENTS: * * - The tag is zero for arityval and non-zero for thing headers. * - A single bit differentiates between positive and negative bignums. * - If more tags are needed, the REF and and EXTERNAL_REF tags could probably *   be combined to one tag. * * XXX: globally replace XXX_SUBTAG with TAG_HEADER_XXX */#define ARITYVAL_SUBTAG		(0x0 << _TAG_PRIMARY_SIZE) /* TUPLE */#define BIN_MATCHSTATE_SUBTAG	(0x1 << _TAG_PRIMARY_SIZE) #define POS_BIG_SUBTAG		(0x2 << _TAG_PRIMARY_SIZE) /* BIG: tags 2&3 */#define NEG_BIG_SUBTAG		(0x3 << _TAG_PRIMARY_SIZE) /* BIG: tags 2&3 */#define _BIG_SIGN_BIT		(0x1 << _TAG_PRIMARY_SIZE)#define REF_SUBTAG		(0x4 << _TAG_PRIMARY_SIZE) /* REF */#define FUN_SUBTAG		(0x5 << _TAG_PRIMARY_SIZE) /* FUN */#define FLOAT_SUBTAG		(0x6 << _TAG_PRIMARY_SIZE) /* FLOAT */#define EXPORT_SUBTAG	(0x7 << _TAG_PRIMARY_SIZE) /* FLOAT */#define _BINARY_XXX_MASK	(0x3 << _TAG_PRIMARY_SIZE)#define REFC_BINARY_SUBTAG	(0x8 << _TAG_PRIMARY_SIZE) /* BINARY */#define HEAP_BINARY_SUBTAG	(0x9 << _TAG_PRIMARY_SIZE) /* BINARY */#define SUB_BINARY_SUBTAG	(0xA << _TAG_PRIMARY_SIZE) /* BINARY */#define EXTERNAL_PID_SUBTAG	(0xC << _TAG_PRIMARY_SIZE) /* EXTERNAL_PID */#define EXTERNAL_PORT_SUBTAG	(0xD << _TAG_PRIMARY_SIZE) /* EXTERNAL_PORT */#define EXTERNAL_REF_SUBTAG	(0xE << _TAG_PRIMARY_SIZE) /* EXTERNAL_REF */#define _TAG_HEADER_ARITYVAL	(TAG_PRIMARY_HEADER|ARITYVAL_SUBTAG)#define _TAG_HEADER_FUN		(TAG_PRIMARY_HEADER|FUN_SUBTAG)#define _TAG_HEADER_POS_BIG	(TAG_PRIMARY_HEADER|POS_BIG_SUBTAG)#define _TAG_HEADER_NEG_BIG	(TAG_PRIMARY_HEADER|NEG_BIG_SUBTAG)#define _TAG_HEADER_FLOAT	(TAG_PRIMARY_HEADER|FLOAT_SUBTAG)#define _TAG_HEADER_EXPORT	(TAG_PRIMARY_HEADER|EXPORT_SUBTAG)#define _TAG_HEADER_REF		(TAG_PRIMARY_HEADER|REF_SUBTAG)#define _TAG_HEADER_REFC_BIN	(TAG_PRIMARY_HEADER|REFC_BINARY_SUBTAG)#define _TAG_HEADER_HEAP_BIN	(TAG_PRIMARY_HEADER|HEAP_BINARY_SUBTAG)#define _TAG_HEADER_SUB_BIN	(TAG_PRIMARY_HEADER|SUB_BINARY_SUBTAG)#define _TAG_HEADER_EXTERNAL_PID  (TAG_PRIMARY_HEADER|EXTERNAL_PID_SUBTAG)#define _TAG_HEADER_EXTERNAL_PORT (TAG_PRIMARY_HEADER|EXTERNAL_PORT_SUBTAG)#define _TAG_HEADER_EXTERNAL_REF  (TAG_PRIMARY_HEADER|EXTERNAL_REF_SUBTAG)#define _TAG_HEADER_BIN_MATCHSTATE (TAG_PRIMARY_HEADER|BIN_MATCHSTATE_SUBTAG)#define _TAG_HEADER_MASK	0x3F#define _HEADER_SUBTAG_MASK	0x3C	/* 4 bits for subtag */#define _HEADER_ARITY_OFFS	6#define header_is_transparent(x) \ (((x) & (_HEADER_SUBTAG_MASK)) == ARITYVAL_SUBTAG)#define header_is_arityval(x)	(((x) & _HEADER_SUBTAG_MASK) == ARITYVAL_SUBTAG)#define header_is_thing(x)	(!header_is_transparent((x)))#define header_is_bin_matchstate(x)	((((x) & (_HEADER_SUBTAG_MASK)) == BIN_MATCHSTATE_SUBTAG))#define _CPMASK		0x3/* immediate object access methods */#define is_immed(x)		(((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_IMMED1)#define is_not_immed(x)		(!is_immed((x)))#define IS_CONST(x)		is_immed((x))#define is_not_both_immed(x,y)	is_not_immed(((x)&(y)))/* boxed object access methods */#define _is_aligned(x)		(((Uint)(x) & 0x3) == 0)#define _unchecked_make_boxed(x)	((Uint)(x) + TAG_PRIMARY_BOXED)_ET_DECLARE_CHECKED(Eterm,make_boxed,Eterm*);#define make_boxed(x)		_ET_APPLY(make_boxed,(x))#if 1#define _is_not_boxed(x)	((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_BOXED))#define _unchecked_is_boxed(x)	(!_is_not_boxed((x)))_ET_DECLARE_CHECKED(int,is_boxed,Eterm);#define is_boxed(x)		_ET_APPLY(is_boxed,(x))#else#define is_boxed(x)		(((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_BOXED)#endif#define _unchecked_boxed_val(x) ((Eterm*)((x) - TAG_PRIMARY_BOXED))_ET_DECLARE_CHECKED(Eterm*,boxed_val,Eterm);#define boxed_val(x)		_ET_APPLY(boxed_val,(x))/* cons cell ("list") access methods */#define _unchecked_make_list(x)	((Uint)(x) + TAG_PRIMARY_LIST)_ET_DECLARE_CHECKED(Eterm,make_list,Eterm*);#define make_list(x)		_ET_APPLY(make_list,(x))#if 1#define _unchecked_is_not_list(x) ((x) & (_TAG_PRIMARY_MASK-TAG_PRIMARY_LIST))_ET_DECLARE_CHECKED(int,is_not_list,Eterm);#define is_not_list(x)		_ET_APPLY(is_not_list,(x))#define is_list(x)		(!is_not_list((x)))#else#define is_list(x)		(((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_LIST)#define is_not_list(x)		(!is_list((x)))#endif#define _unchecked_list_val(x)	((Eterm*)((x) - TAG_PRIMARY_LIST))_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);#define list_val(x)		_ET_APPLY(list_val,(x))#define CONS(hp, car, cdr) \        (CAR(hp)=(car), CDR(hp)=(cdr), make_list(hp))#define CAR(x)  ((x)[0])#define CDR(x)  ((x)[1])/* generic tagged pointer (boxed or list) access methods */#define _unchecked_ptr_val(x)	((Eterm*)((x) & ~((Uint) 0x3)))#define ptr_val(x)		_unchecked_ptr_val((x))	/*XXX*/#define _unchecked_offset_ptr(x,offs)	((x)+((offs)*sizeof(Eterm)))#define offset_ptr(x,offs)	_unchecked_offset_ptr(x,offs)	/*XXX*//* fixnum ("small") access methods */#if defined(ARCH_64)#define SMALL_BITS	(64-4)#define SMALL_DIGITS	(17)#else#define SMALL_BITS	(28)#define SMALL_DIGITS	(8)#endif#define MAX_SMALL	((1L << (SMALL_BITS-1))-1)#define MIN_SMALL	(-(1L << (SMALL_BITS-1)))#define make_small(x)	(((Uint)(x) << _TAG_IMMED1_SIZE) + _TAG_IMMED1_SMALL)#define is_small(x)	(((x) & _TAG_IMMED1_MASK) == _TAG_IMMED1_SMALL)#define is_not_small(x)	(!is_small((x)))#define is_byte(x)	(((x) & ((~(Uint)0 << (_TAG_IMMED1_SIZE+8)) + _TAG_IMMED1_MASK)) == _TAG_IMMED1_SMALL)#define is_valid_bit_size(x) (((Sint)(x)) >= 0 && ((x) & 0x7F) == _TAG_IMMED1_SMALL)#define is_not_valid_bit_size(x) (!is_valid_bit_size((x)))#define MY_IS_SSMALL(x) (((Uint) (((x) >> (SMALL_BITS-1)) + 1)) < 2)#define _unchecked_unsigned_val(x)	((x) >> _TAG_IMMED1_SIZE)_ET_DECLARE_CHECKED(Uint,unsigned_val,Eterm);#define unsigned_val(x)	_ET_APPLY(unsigned_val,(x))#define _unchecked_signed_val(x)	((Sint)(x) >> _TAG_IMMED1_SIZE)_ET_DECLARE_CHECKED(Sint,signed_val,Eterm);#define signed_val(x)	_ET_APPLY(signed_val,(x))#if _TAG_IMMED1_SMALL == 0x0F#define is_both_small(x,y) (((x) & (y) & _TAG_IMMED1_MASK) == _TAG_IMMED1_SMALL)#elif _TAG_IMMED1_SMALL == 0x00#define is_both_small(x,y) ((((x)|(y)) & _TAG_IMMED1_MASK) == _TAG_IMMED1_SMALL)#else#define is_both_small(x,y) (is_small(x) && is_small(y))#endif/* NIL access methods */#define NIL		((~((Uint) 0) << _TAG_IMMED2_SIZE) | _TAG_IMMED2_NIL)#define is_nil(x)	((x) == NIL)#define is_not_nil(x)	((x) != NIL)#define MAX_ATOM_INDEX (~(~((Uint) 0) << (sizeof(Uint)*8 - _TAG_IMMED2_SIZE)))/* atom access methods */#define make_atom(x)	(((x) << _TAG_IMMED2_SIZE) + _TAG_IMMED2_ATOM)#define is_atom(x)	(((x) & _TAG_IMMED2_MASK) == _TAG_IMMED2_ATOM)#define is_not_atom(x)	(!is_atom(x))#define _unchecked_atom_val(x)	((x) >> _TAG_IMMED2_SIZE)_ET_DECLARE_CHECKED(Uint,atom_val,Eterm);#define atom_val(x)	_ET_APPLY(atom_val,(x))/* header (arityval or thing) access methods */#define _make_header(sz,tag)	(((sz) << _HEADER_ARITY_OFFS) + (tag))#define is_header(x)	(((x) & _TAG_PRIMARY_MASK) == TAG_PRIMARY_HEADER)#define _unchecked_header_arity(x)	((x) >> _HEADER_ARITY_OFFS)_ET_DECLARE_CHECKED(Uint,header_arity,Eterm);#define header_arity(x)	_ET_APPLY(header_arity,(x))/* arityval access methods */#define make_arityval(sz)	_make_header((sz),_TAG_HEADER_ARITYVAL)#define is_arity_value(x)	(((x) & _TAG_HEADER_MASK) == _TAG_HEADER_ARITYVAL)#define is_not_arity_value(x)	(!is_arity_value((x)))#define _unchecked_arityval(x)	_unchecked_header_arity((x))_ET_DECLARE_CHECKED(Uint,arityval,Eterm);#define arityval(x)		_ET_APPLY(arityval,(x))/* thing access methods */#define is_thing(x)	(is_header((x)) && header_is_thing((x)))#define _unchecked_thing_arityval(x)	_unchecked_header_arity((x))_ET_DECLARE_CHECKED(Uint,thing_arityval,Eterm);#define thing_arityval(x)	_ET_APPLY(thing_arityval,(x))#define _unchecked_thing_subtag(x)	((x) & _HEADER_SUBTAG_MASK)_ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm);#define thing_subtag(x)		_ET_APPLY(thing_subtag,(x))/* * Magic non-value object. * Used as function return error and "absent value" indicator * in the original runtime system. The new runtime system also * uses it as forwarding marker for CONS cells. * * This value is 0 in the original runtime system, which unfortunately * promotes sloppy programming practices. It also prevents some useful * tag assignment schemes, e.g. using a 2-bit tag 00 for FIXNUM. * * To help find code which makes unwarranted assumptions about zero, * we now use a non-zero bit-pattern in debug mode. */#if ET_DEBUG#define THE_NON_VALUE	_make_header(0,_TAG_HEADER_FLOAT)#else#define THE_NON_VALUE	(0)#endif#define is_non_value(x)	((x) == THE_NON_VALUE)#define is_value(x)	((x) != THE_NON_VALUE)/* binary object access methods */#define is_binary_header(x)	(((x) & (_TAG_HEADER_MASK-_BINARY_XXX_MASK)) == _TAG_HEADER_REFC_BIN)#define make_binary(x)	make_boxed((Eterm*)(x))#define is_binary(x)	(is_boxed((x)) && is_binary_header(*boxed_val((x))))#define is_not_binary(x) (!is_binary((x)))#define _unchecked_binary_val(x) _unchecked_boxed_val((x))_ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm);#define binary_val(x)	_ET_APPLY(binary_val,(x))/* process binaries stuff (special case of binaries) */#define HEADER_PROC_BIN	_make_header(PROC_BIN_SIZE-1,_TAG_HEADER_REFC_BIN)/* fun & export objects */#define is_any_fun(x)   (is_fun((x)) || is_export((x)))#define is_not_any_fun(x) (!is_any_fun((x)))/* fun objects */#define HEADER_FUN		_make_header(ERL_FUN_SIZE-2,_TAG_HEADER_FUN)#define is_fun_header(x)	((x) == HEADER_FUN)#define make_fun(x)		make_boxed((Eterm*)(x))#define is_fun(x)		(is_boxed((x)) && is_fun_header(*boxed_val((x))))#define is_not_fun(x)		(!is_fun((x)))#define _unchecked_fun_val(x)   _unchecked_boxed_val((x))_ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm);#define fun_val(x)		_ET_APPLY(fun_val,(x))/* export access methods */#define make_export(x)	 make_boxed((x))#define is_export(x)     (is_boxed((x)) && is_export_header(*boxed_val((x))))#define is_not_export(x) (!is_export((x)))#define _unchecked_export_val(x)   _unchecked_boxed_val(x)_ET_DECLARE_CHECKED(Eterm*,export_val,Eterm);#define export_val(x)	_ET_APPLY(export_val,(x))#define is_export_header(x)	((x) == HEADER_EXPORT)#define HEADER_EXPORT   _make_header(1,_TAG_HEADER_EXPORT)/* bignum access methods */#define make_pos_bignum_header(sz)	_make_header((sz),_TAG_HEADER_POS_BIG)#define make_neg_bignum_header(sz)	_make_header((sz),_TAG_HEADER_NEG_BIG)#define _is_bignum_header(x)	(((x) & (_TAG_HEADER_MASK-_BIG_SIGN_BIT)) == _TAG_HEADER_POS_BIG)#define _unchecked_bignum_header_is_neg(x)	((x) & _BIG_SIGN_BIT)_ET_DECLARE_CHECKED(int,bignum_header_is_neg,Eterm);#define bignum_header_is_neg(x)	_ET_APPLY(bignum_header_is_neg,(x))#define _unchecked_bignum_header_neg(x)	((x) | _BIG_SIGN_BIT)_ET_DECLARE_CHECKED(Eterm,bignum_header_neg,Eterm);#define bignum_header_neg(x)	_ET_APPLY(bignum_header_neg,(x))#define _unchecked_bignum_header_arity(x)	_unchecked_header_arity((x))_ET_DECLARE_CHECKED(Uint,bignum_header_arity,Eterm);#define bignum_header_arity(x)	_ET_APPLY(bignum_header_arity,(x))#define BIG_ARITY_MAX		((1 << 19)-1)#define make_big(x)	make_boxed((x))#define is_big(x)	(is_boxed((x)) && _is_bignum_header(*boxed_val((x))))#define is_not_big(x)	(!is_big((x)))#define _unchecked_big_val(x)	_unchecked_boxed_val((x))_ET_DECLARE_CHECKED(Eterm*,big_val,Eterm);#define big_val(x)		_ET_APPLY(big_val,(x))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -