aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorFilipe David Manana <[email protected]>2011-05-16 17:00:25 +0100
committerFilipe David Manana <[email protected]>2011-08-27 21:16:21 -0700
commit1b2cea397131a36a39b18c6ce8c6944bf11db4c7 (patch)
treee3f6ec427883d36e3ab8104ee73eb1c9c5966fcb /erts/emulator/beam
parent9a52e239698ae62cddbc0d780502c72458867b6f (diff)
downloadotp-1b2cea397131a36a39b18c6ce8c6944bf11db4c7.tar.gz
otp-1b2cea397131a36a39b18c6ce8c6944bf11db4c7.tar.bz2
otp-1b2cea397131a36a39b18c6ce8c6944bf11db4c7.zip
Add erlang:external_size/2 BIF
This BIF's second parameter is a list of options. Currently the only allowed option is {minor_version, Version} where version is either 0 (default) or 1.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/bif.tab2
-rw-r--r--erts/emulator/beam/external.c49
-rw-r--r--erts/emulator/beam/external.h1
3 files changed, 52 insertions, 0 deletions
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index b171e99e03..831c0b1ce6 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -87,6 +87,8 @@ bif erlang:exit/2
bif 'erl.lang.proc':signal/2 ebif_signal_2 exit_2
bif erlang:external_size/1
bif 'erl.lang.term':external_size/1 ebif_external_size_1
+bif erlang:external_size/2
+bif 'erl.lang.term':external_size/2 ebif_external_size_2
ubif erlang:float/1
ubif 'erl.lang.number':to_float/1 ebif_to_float_1 float_1
bif erlang:float_to_list/1
diff --git a/erts/emulator/beam/external.c b/erts/emulator/beam/external.c
index 1a102f7187..6953e7fe7d 100644
--- a/erts/emulator/beam/external.c
+++ b/erts/emulator/beam/external.c
@@ -459,6 +459,12 @@ Uint erts_encode_ext_size(Eterm term)
+ 1 /* VERSION_MAGIC */;
}
+Uint erts_encode_ext_size_2(Eterm term, unsigned dflags)
+{
+ return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|dflags)
+ + 1 /* VERSION_MAGIC */;
+}
+
Uint erts_encode_ext_size_ets(Eterm term)
{
return encode_size_struct2(NULL, term, TERM_TO_BINARY_DFLAGS|DFLAGS_INTERNAL_TAGS);
@@ -1262,6 +1268,49 @@ external_size_1(Process* p, Eterm Term)
}
Eterm
+external_size_2(Process* p, Eterm Term, Eterm Flags)
+{
+ Uint size;
+ Uint flags = TERM_TO_BINARY_DFLAGS;
+
+ while (is_list(Flags)) {
+ Eterm arg = CAR(list_val(Flags));
+ Eterm* tp;
+
+ if (is_tuple(arg) && *(tp = tuple_val(arg)) == make_arityval(2)) {
+ if (tp[1] == am_minor_version && is_small(tp[2])) {
+ switch (signed_val(tp[2])) {
+ case 0:
+ break;
+ case 1:
+ flags |= DFLAG_NEW_FLOATS;
+ break;
+ default:
+ goto error;
+ }
+ } else {
+ goto error;
+ }
+ } else {
+ error:
+ BIF_ERROR(p, BADARG);
+ }
+ Flags = CDR(list_val(Flags));
+ }
+ if (is_not_nil(Flags)) {
+ goto error;
+ }
+
+ size = erts_encode_ext_size_2(Term, flags);
+ if (IS_USMALL(0, size)) {
+ BIF_RET(make_small(size));
+ } else {
+ Eterm* hp = HAlloc(p, BIG_UINT_HEAP_SIZE);
+ BIF_RET(uint_to_big(size, hp));
+ }
+}
+
+Eterm
erts_term_to_binary(Process* p, Eterm Term, int level, Uint flags)
{
Uint size;
diff --git a/erts/emulator/beam/external.h b/erts/emulator/beam/external.h
index d8287b96a4..72fe74baf2 100644
--- a/erts/emulator/beam/external.h
+++ b/erts/emulator/beam/external.h
@@ -160,6 +160,7 @@ Uint erts_encode_dist_ext_size(Eterm, Uint32, ErtsAtomCacheMap *);
void erts_encode_dist_ext(Eterm, byte **, Uint32, ErtsAtomCacheMap *);
Uint erts_encode_ext_size(Eterm);
+Uint erts_encode_ext_size_2(Eterm, unsigned);
Uint erts_encode_ext_size_ets(Eterm);
void erts_encode_ext(Eterm, byte **);
byte* erts_encode_ext_ets(Eterm, byte *, struct erl_off_heap_header** ext_off_heap);