aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/bif.c9
-rw-r--r--erts/emulator/beam/erl_binary.h14
-rw-r--r--erts/emulator/beam/erl_term.h108
-rw-r--r--erts/emulator/beam/global.h65
-rw-r--r--erts/emulator/beam/utils.c8
5 files changed, 122 insertions, 82 deletions
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 9c8c0df9f0..1b670585a7 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4143,6 +4143,7 @@ BIF_RETTYPE blocking_read_file_1(BIF_ALIST_1)
FILE *file;
struct stat file_info;
char *filename = NULL;
+ size_t size;
i = list_length(BIF_ARG_1);
if (i < 0) {
@@ -4170,9 +4171,13 @@ BIF_RETTYPE blocking_read_file_1(BIF_ALIST_1)
fclose(file);
BIF_RET(TUPLE2(hp, am_error, am_allocator));
}
- fread(buff, 1, buff_size, file);
+ size = fread(buff, 1, buff_size, file);
fclose(file);
- bin = new_binary(BIF_P, buff, buff_size);
+ if (size < 0)
+ size = 0;
+ else if (size > buff_size)
+ size = (size_t) buff_size;
+ bin = new_binary(BIF_P, buff, (int) size);
erts_free(ERTS_ALC_T_TMP, (void *) buff);
BIF_RET(TUPLE2(hp, am_ok, bin));
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index dc5539faad..f8ecdde997 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* 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 online 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.
- *
+ *
* %CopyrightEnd%
*/
@@ -265,13 +265,13 @@ erts_bin_free(Binary *bp)
ERTS_GLB_INLINE Binary *
erts_create_magic_binary(Uint size, void (*destructor)(Binary *))
{
- Uint bsize = sizeof(Binary) - 1 + sizeof(ErtsBinaryMagicPart) - 1 + size;
+ Uint bsize = ERTS_MAGIC_BIN_SIZE(size);
Binary* bptr = erts_alloc_fnf(ERTS_ALC_T_BINARY, bsize);
if (!bptr)
erts_alloc_n_enomem(ERTS_ALC_T2N(ERTS_ALC_T_BINARY), bsize);
ERTS_CHK_BIN_ALIGNMENT(bptr);
bptr->flags = BIN_FLAG_MAGIC;
- bptr->orig_size = sizeof(ErtsBinaryMagicPart) - 1 + size;
+ bptr->orig_size = ERTS_MAGIC_BIN_ORIG_SIZE(size);
erts_refc_init(&bptr->refc, 0);
ERTS_MAGIC_BIN_DESTRUCTOR(bptr) = destructor;
return bptr;
diff --git a/erts/emulator/beam/erl_term.h b/erts/emulator/beam/erl_term.h
index b0a57a3ebe..a6596558fa 100644
--- a/erts/emulator/beam/erl_term.h
+++ b/erts/emulator/beam/erl_term.h
@@ -1,19 +1,19 @@
/*
* %CopyrightBegin%
- *
- * Copyright Ericsson AB 2000-2009. All Rights Reserved.
- *
+ *
+ * Copyright Ericsson AB 2000-2010. All Rights Reserved.
+ *
* 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 online 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.
- *
+ *
* %CopyrightEnd%
*/
@@ -38,7 +38,7 @@ struct erl_node_; /* Declared in erl_node_tables.h */
#endif
#if ET_DEBUG
-#define _ET_DECLARE_CHECKED(TF,F,TX) extern TF checked_##F(TX,const char*,unsigned)
+#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)
@@ -160,27 +160,27 @@ struct erl_node_; /* Declared in erl_node_tables.h */
/* 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*);
+_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);
+_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);
+_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*);
+_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);
+_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
@@ -188,7 +188,7 @@ _ET_DECLARE_CHECKED(int,is_not_list,Eterm);
#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);
+_ET_DECLARE_CHECKED(Eterm*,list_val,Eterm)
#define list_val(x) _ET_APPLY(list_val,(x))
#define CONS(hp, car, cdr) \
@@ -221,10 +221,10 @@ _ET_DECLARE_CHECKED(Eterm*,list_val,Eterm);
#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);
+_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);
+_ET_DECLARE_CHECKED(Sint,signed_val,Eterm)
#define signed_val(x) _ET_APPLY(signed_val,(x))
#if _TAG_IMMED1_SMALL == 0x0F
@@ -247,14 +247,14 @@ _ET_DECLARE_CHECKED(Sint,signed_val,Eterm);
#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);
+_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) ((Uint)(((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);
+_ET_DECLARE_CHECKED(Uint,header_arity,Eterm)
#define header_arity(x) _ET_APPLY(header_arity,(x))
/* arityval access methods */
@@ -262,16 +262,16 @@ _ET_DECLARE_CHECKED(Uint,header_arity,Eterm);
#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);
+_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);
+_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);
+_ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm)
#define thing_subtag(x) _ET_APPLY(thing_subtag,(x))
/*
@@ -301,7 +301,7 @@ _ET_DECLARE_CHECKED(Uint,thing_subtag,Eterm);
#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);
+_ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm)
#define binary_val(x) _ET_APPLY(binary_val,(x))
/* process binaries stuff (special case of binaries) */
@@ -318,7 +318,7 @@ _ET_DECLARE_CHECKED(Eterm*,binary_val,Eterm);
#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);
+_ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm)
#define fun_val(x) _ET_APPLY(fun_val,(x))
/* export access methods */
@@ -326,7 +326,7 @@ _ET_DECLARE_CHECKED(Eterm*,fun_val,Eterm);
#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);
+_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)
@@ -336,20 +336,20 @@ _ET_DECLARE_CHECKED(Eterm*,export_val,Eterm);
#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);
+_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);
+_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);
+_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);
+_ET_DECLARE_CHECKED(Eterm*,big_val,Eterm)
#define big_val(x) _ET_APPLY(big_val,(x))
/* flonum ("float") access methods */
@@ -362,7 +362,7 @@ _ET_DECLARE_CHECKED(Eterm*,big_val,Eterm);
#define is_float(x) (is_boxed((x)) && *boxed_val((x)) == HEADER_FLONUM)
#define is_not_float(x) (!is_float(x))
#define _unchecked_float_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,float_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,float_val,Eterm)
#define float_val(x) _ET_APPLY(float_val,(x))
/* Float definition for byte and word access */
@@ -409,7 +409,7 @@ typedef union float_def
(is_boxed((x)) && *boxed_val((x)) == make_arityval((a)))
#define is_not_tuple_arity(x, a) (!is_tuple_arity((x),(a)))
#define _unchecked_tuple_val(x) _unchecked_boxed_val(x)
-_ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm);
+_ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm)
#define tuple_val(x) _ET_APPLY(tuple_val,(x))
#define TUPLE0(t) \
@@ -548,11 +548,11 @@ _ET_DECLARE_CHECKED(Eterm*,tuple_val,Eterm);
#define is_not_internal_pid(x) (!is_internal_pid((x)))
#define _unchecked_internal_pid_data(x) _GET_PID_DATA((x))
-_ET_DECLARE_CHECKED(Uint,internal_pid_data,Eterm);
+_ET_DECLARE_CHECKED(Uint,internal_pid_data,Eterm)
#define internal_pid_data(x) _ET_APPLY(internal_pid_data,(x))
#define _unchecked_internal_pid_node(x) erts_this_node
-_ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm)
#define internal_pid_node(x) _ET_APPLY(internal_pid_node,(x))
#define internal_pid_number(x) _GET_PID_NUM(internal_pid_data((x)))
@@ -604,13 +604,13 @@ _ET_DECLARE_CHECKED(struct erl_node_*,internal_pid_node,Eterm);
#define is_not_internal_port(x) (!is_internal_port(x))
#define _unchecked_internal_port_data(x) _GET_PORT_DATA((x))
-_ET_DECLARE_CHECKED(Uint,internal_port_data,Eterm);
+_ET_DECLARE_CHECKED(Uint,internal_port_data,Eterm)
#define internal_port_data(x) _ET_APPLY(internal_port_data,(x))
#define internal_port_number(x) _GET_PORT_NUM(internal_port_data((x)))
#define _unchecked_internal_port_node(x) erts_this_node
-_ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm);
+_ET_DECLARE_CHECKED(struct erl_node_*,internal_port_node,Eterm)
#define internal_port_node(x) _ET_APPLY(internal_port_node,(x))
#define internal_port_data_words(x) (1)
@@ -753,20 +753,20 @@ do { \
(!is_internal_ref((x)))
#define _unchecked_internal_ref_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,internal_ref_val,Eterm);
+_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);
+_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.ui32)
-_ET_DECLARE_CHECKED(Uint32*,internal_ref_data,Eterm);
+_ET_DECLARE_CHECKED(Uint32*,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);
+_ET_DECLARE_CHECKED(struct erl_node_*,internal_ref_node,Eterm)
#define internal_ref_node(x) _ET_APPLY(internal_ref_node,(x))
/*
@@ -864,7 +864,7 @@ typedef struct external_thing_ {
#define make_external_ref make_external
#define _unchecked_external_val(x) _unchecked_boxed_val((x))
-_ET_DECLARE_CHECKED(Eterm*,external_val,Eterm);
+_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)))
@@ -874,7 +874,7 @@ _ET_DECLARE_CHECKED(Eterm*,external_val,Eterm);
#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);
+_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.ui)
@@ -885,15 +885,15 @@ _ET_DECLARE_CHECKED(Uint,external_data_words,Eterm);
#define _unchecked_external_pid_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_pid_data_words,Eterm);
+_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);
+_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);
+_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)))
@@ -901,30 +901,30 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_pid_node,Eterm);
#define _unchecked_external_port_data_words(x) \
_unchecked_external_data_words((x))
-_ET_DECLARE_CHECKED(Uint,external_port_data_words,Eterm);
+_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);
+_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);
+_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);
+_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_thing_ptr((x))->data.ui32)
-_ET_DECLARE_CHECKED(Uint32*,external_ref_data,Eterm);
+_ET_DECLARE_CHECKED(Uint32*,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);
+_ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm)
#define external_ref_node(x) _ET_APPLY(external_ref_node,(x))
/* number tests */
@@ -945,21 +945,21 @@ _ET_DECLARE_CHECKED(struct erl_node_*,external_ref_node,Eterm);
#endif
#define _unchecked_make_cp(x) ((Eterm)(x))
-_ET_DECLARE_CHECKED(Eterm,make_cp,Uint*);
+_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);
+_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);
+_ET_DECLARE_CHECKED(Uint,catch_val,Eterm)
#define catch_val(x) _ET_APPLY(catch_val,(x))
#define make_blank(X) ((X) = NIL)
@@ -989,21 +989,21 @@ _ET_DECLARE_CHECKED(Uint,catch_val,Eterm);
#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);
+_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);
+_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);
+_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);
+_ET_DECLARE_CHECKED(Uint,y_reg_index,Uint)
#define y_reg_index(R) _ET_APPLY(y_reg_index,(R))
/*
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index df0ab40074..8def007c63 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -21,6 +21,7 @@
#define __GLOBAL_H__
#include "sys.h"
+#include <stddef.h> /* offsetof() */
#include "erl_alloc.h"
#include "erl_vm.h"
#include "erl_node_container_utils.h"
@@ -382,17 +383,42 @@ extern Eterm erts_ddll_monitor_driver(Process *p,
** and Binary, the macros below can convert one type to the other, as they both
** in reality are equal.
*/
-typedef struct binary {
- Uint flags;
- erts_refc_t refc;
+
#ifdef ARCH_32
- Uint32 align__; /* *DO NOT USE* only for alignment. */
+ /* *DO NOT USE* only for alignment. */
+#define ERTS_BINARY_STRUCT_ALIGNMENT Uint32 align__;
+#else
+#define ERTS_BINARY_STRUCT_ALIGNMENT
#endif
- /* Add fields BEFORE this, otherwise the drivers crash */
+
+/* Add fields in ERTS_INTERNAL_BINARY_FIELDS, otherwise the drivers crash */
+#define ERTS_INTERNAL_BINARY_FIELDS \
+ Uint flags; \
+ erts_refc_t refc; \
+ ERTS_BINARY_STRUCT_ALIGNMENT
+
+typedef struct binary {
+ ERTS_INTERNAL_BINARY_FIELDS
long orig_size;
char orig_bytes[1]; /* to be continued */
} Binary;
+typedef struct {
+ ERTS_INTERNAL_BINARY_FIELDS
+ long orig_size;
+ void (*destructor)(Binary *);
+ char magic_bin_data[1];
+} ErtsMagicBinary;
+
+typedef union {
+ Binary binary;
+ ErtsMagicBinary magic_binary;
+ struct {
+ ERTS_INTERNAL_BINARY_FIELDS
+ ErlDrvBinary binary;
+ } driver;
+} ErtsBinary;
+
/*
* 'Binary' alignment:
* Address of orig_bytes[0] of a Binary should always be 8-byte aligned.
@@ -400,25 +426,21 @@ typedef struct binary {
* 32-bits architectures and 8 bytes on 64-bits architectures.
*/
-/*
- * "magic" binary.
- */
-typedef struct {
- void (*destructor)(Binary *);
- char magic_bin_data[1];
-} ErtsBinaryMagicPart;
-
#define ERTS_MAGIC_BIN_DESTRUCTOR(BP) \
- (((ErtsBinaryMagicPart *) (BP)->orig_bytes)->destructor)
+ ((ErtsBinary *) (BP))->magic_binary.destructor
#define ERTS_MAGIC_BIN_DATA(BP) \
- ((void *) (((ErtsBinaryMagicPart *) (BP)->orig_bytes)->magic_bin_data))
+ ((void *) ((ErtsBinary *) (BP))->magic_binary.magic_bin_data)
#define ERTS_MAGIC_BIN_DATA_SIZE(BP) \
- ((BP)->orig_size - (sizeof(ErtsBinaryMagicPart) - 1))
+ ((BP)->orig_size - sizeof(void (*)(Binary *)))
+#define ERTS_MAGIC_BIN_ORIG_SIZE(Sz) \
+ (sizeof(void (*)(Binary *)) + (Sz))
+#define ERTS_MAGIC_BIN_SIZE(Sz) \
+ (sizeof(ErtsMagicBinary) - 1 + (Sz))
-#define Binary2ErlDrvBinary(B) ((ErlDrvBinary *) (&((B)->orig_size)))
+#define Binary2ErlDrvBinary(B) (&((ErtsBinary *) (B))->driver.binary)
#define ErlDrvBinary2Binary(D) ((Binary *) \
- (((char *) (D)) - \
- ((char *) &(((Binary *) 0)->orig_size))))
+ (((char *) (D)) \
+ - offsetof(ErtsBinary, driver.binary)))
/* A "magic" binary flag */
#define BIN_FLAG_MAGIC 1
@@ -1406,6 +1428,11 @@ void p_slpq(_VOID_);
/* utils.c */
+/*
+ * To be used to silence unused result warnings, but do not abuse it.
+ */
+void erts_silence_warn_unused_result(long unused);
+
void erts_cleanup_offheap(ErlOffHeap *offheap);
void erts_cleanup_externals(ExternalThing *);
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index c162395159..687e6fa67b 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -3982,6 +3982,14 @@ erts_write_env(char *key, char *value)
return res;
}
+/*
+ * To be used to silence unused result warnings, but do not abuse it.
+ */
+void erts_silence_warn_unused_result(long unused)
+{
+
+}
+
#ifdef DEBUG
/*
* Handy functions when using a debugger - don't use in the code!