aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
Diffstat (limited to 'erts')
-rw-r--r--erts/aclocal.m42
-rwxr-xr-xerts/autoconf/config.guess342
-rwxr-xr-xerts/autoconf/config.sub69
-rw-r--r--erts/configure.in23
-rw-r--r--erts/doc/src/erl_nif.xml81
-rw-r--r--erts/doc/src/notes.xml16
-rw-r--r--erts/emulator/beam/beam_emu.c133
-rw-r--r--erts/emulator/beam/beam_load.c6
-rw-r--r--erts/emulator/beam/erl_alloc.types5
-rw-r--r--erts/emulator/beam/erl_bits.c29
-rw-r--r--erts/emulator/beam/erl_init.c2
-rw-r--r--erts/emulator/beam/erl_nif.c22
-rw-r--r--erts/emulator/beam/erl_nif.h3
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h2
-rw-r--r--erts/emulator/beam/erl_process.c8
-rw-r--r--erts/emulator/beam/global.h1
-rw-r--r--erts/emulator/beam/io.c4
-rw-r--r--erts/emulator/beam/ops.tab110
-rw-r--r--erts/emulator/beam/utils.c22
-rw-r--r--erts/emulator/hipe/hipe_amd64_bifs.m459
-rw-r--r--erts/emulator/hipe/hipe_arm_asm.m45
-rw-r--r--erts/emulator/hipe/hipe_arm_bifs.m436
-rw-r--r--erts/emulator/hipe/hipe_arm_glue.S12
-rw-r--r--erts/emulator/hipe/hipe_bif0.c7
-rw-r--r--erts/emulator/hipe/hipe_bif0.tab1
-rw-r--r--erts/emulator/hipe/hipe_bif_list.m42
-rw-r--r--erts/emulator/hipe/hipe_native_bif.h3
-rw-r--r--erts/emulator/hipe/hipe_ppc_glue.S6
-rw-r--r--erts/emulator/hipe/hipe_primops.h1
-rw-r--r--erts/emulator/hipe/hipe_sparc_bifs.m42
-rw-r--r--erts/emulator/hipe/hipe_x86_bifs.m42
-rw-r--r--erts/emulator/sys/ose/erl_ose_sys.h2
-rw-r--r--erts/emulator/sys/unix/erl_unix_sys.h2
-rw-r--r--erts/emulator/sys/win32/erl_win_sys.h2
-rw-r--r--erts/emulator/test/beam_literals_SUITE.erl17
-rw-r--r--erts/emulator/test/code_parallel_load_SUITE.erl10
-rw-r--r--erts/emulator/test/nif_SUITE.erl82
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c104
-rw-r--r--erts/emulator/test/op_SUITE.erl12
-rw-r--r--erts/emulator/test/trace_bif_SUITE.erl13
-rw-r--r--erts/etc/common/ct_run.c2
-rw-r--r--erts/etc/common/heart.c25
-rw-r--r--erts/etc/common/run_erl_common.c4
-rw-r--r--erts/etc/unix/etp-commands.in65
44 files changed, 956 insertions, 400 deletions
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 83f735d332..73fa5d3603 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -559,7 +559,7 @@ dnl
AC_DEFUN(LM_SYS_MULTICAST,
[AC_CACHE_CHECK([for multicast support], ac_cv_sys_multicast_support,
-[AC_EGREP_CPP(yes,
+[AC_EGREP_CPP(^yes$,
[#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
diff --git a/erts/autoconf/config.guess b/erts/autoconf/config.guess
index f475ceb413..f7eb141e75 100755
--- a/erts/autoconf/config.guess
+++ b/erts/autoconf/config.guess
@@ -1,8 +1,8 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright 1992-2013 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2013-02-12'
+timestamp='2015-03-04'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -24,12 +24,12 @@ timestamp='2013-02-12'
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
-# Originally written by Per Bothner.
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
-# Please send patches with a ChangeLog entry to [email protected].
+# Please send patches to <[email protected]>.
me=`echo "$0" | sed -e 's,.*/,,'`
@@ -50,7 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -132,6 +132,27 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
@@ -147,20 +168,27 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ELF__
@@ -176,6 +204,13 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
os=netbsd
;;
esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
@@ -192,7 +227,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
+ echo "${machine}-${os}${release}${abi}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
@@ -558,8 +593,9 @@ EOF
else
IBM_ARCH=powerpc
fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
@@ -805,7 +841,7 @@ EOF
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
- i*:MSYS*:*)
+ *:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
@@ -853,21 +889,21 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
@@ -880,59 +916,57 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
- echo ${UNAME_MACHINE}-axis-linux-gnu
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
frv:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
@@ -951,57 +985,63 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
- or1k:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
exit ;;
- or32:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
+ echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
+ echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
+ echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1234,19 +1274,31 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1337,154 +1389,6 @@ EOF
exit ;;
esac
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
cat >&2 <<EOF
$0: unable to guess system type
diff --git a/erts/autoconf/config.sub b/erts/autoconf/config.sub
index bb6edbdb47..8f1229c6f7 100755
--- a/erts/autoconf/config.sub
+++ b/erts/autoconf/config.sub
@@ -1,8 +1,8 @@
#! /bin/sh
# Configuration validation subroutine script.
-# Copyright 1992-2013 Free Software Foundation, Inc.
+# Copyright 1992-2015 Free Software Foundation, Inc.
-timestamp='2013-02-12'
+timestamp='2015-03-08'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -25,7 +25,7 @@ timestamp='2013-02-12'
# of the GNU General Public License, version 3 ("GPLv3").
-# Please send patches with a ChangeLog entry to [email protected].
+# Please send patches to <[email protected]>.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@@ -68,7 +68,7 @@ Report bugs and patches to <[email protected]>."
version="\
GNU config.sub ($timestamp)
-Copyright 1992-2013 Free Software Foundation, Inc.
+Copyright 1992-2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -117,7 +117,7 @@ maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
- knetbsd*-gnu* | netbsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
@@ -252,19 +252,20 @@ case $basic_machine in
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
- | arc \
+ | arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
- | c4x | clipper \
+ | c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
- | epiphany \
- | fido | fr30 | frv \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
+ | k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
@@ -282,8 +283,10 @@ case $basic_machine in
| mips64vr5900 | mips64vr5900el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
| mipsisa64 | mipsisa64el \
| mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
@@ -295,11 +298,11 @@ case $basic_machine in
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
- | open8 \
- | or1k | or32 \
+ | open8 | or1k | or1knd | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
+ | riscv32 | riscv64 \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
@@ -310,6 +313,7 @@ case $basic_machine in
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
| we32k \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
@@ -324,7 +328,10 @@ case $basic_machine in
c6x)
basic_machine=tic6x-unknown
;;
- m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip)
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@@ -366,21 +373,22 @@ case $basic_machine in
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
- | clipper-* | craynv-* | cydra-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
- | elxsi-* \
+ | e2k-* | elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
+ | k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
@@ -400,8 +408,10 @@ case $basic_machine in
| mips64vr5900-* | mips64vr5900el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
@@ -413,6 +423,7 @@ case $basic_machine in
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
+ | or1k*-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
@@ -430,6 +441,7 @@ case $basic_machine in
| ubicom32-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
+ | visium-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
@@ -506,6 +518,9 @@ case $basic_machine in
basic_machine=i386-pc
os=-aros
;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
aux)
basic_machine=m68k-apple
os=-aux
@@ -767,6 +782,9 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
m68knommu)
basic_machine=m68k-unknown
os=-linux
@@ -794,7 +812,7 @@ case $basic_machine in
os=-mingw64
;;
mingw32)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@@ -822,6 +840,10 @@ case $basic_machine in
basic_machine=powerpc-unknown
os=-morphos
;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
msdos)
basic_machine=i386-pc
os=-msdos
@@ -830,7 +852,7 @@ case $basic_machine in
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
- basic_machine=i386-pc
+ basic_machine=i686-pc
os=-msys
;;
mvs)
@@ -1354,7 +1376,7 @@ case $os in
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
+ | -aos* | -aros* | -cloudabi* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
@@ -1367,14 +1389,14 @@ case $os in
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1546,6 +1568,9 @@ case $basic_machine in
c4x-* | tic4x-*)
os=-coff
;;
+ c8051-*)
+ os=-elf
+ ;;
hexagon-*)
os=-elf
;;
@@ -1589,9 +1614,6 @@ case $basic_machine in
mips*-*)
os=-elf
;;
- or1k-*)
- os=-elf
- ;;
or32-*)
os=-coff
;;
@@ -1786,4 +1808,3 @@ exit
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
-
diff --git a/erts/configure.in b/erts/configure.in
index 9d88d5849a..91c06973ac 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -631,7 +631,7 @@ fi
case $chk_opsys_ in
win32) OPSYS=win32;;
solaris2.*|SunOS5.*) OPSYS=sol2;;
- linux|Linux) OPSYS=linux;;
+ linux*|Linux) OPSYS=linux;;
darwin|Darwin) OPSYS=darwin;;
freebsd|FreeBSD) OPSYS=freebsd;;
*) OPSYS=noopsys
@@ -1558,10 +1558,11 @@ if test "$have_gethostbyname_r" = yes; then
[Define to flavour of gethostbyname_r]))
;;
*)
- AC_EGREP_CPP(yes,[#include <stdio.h>
- #ifdef __GLIBC__
- yes
- #endif
+ AC_EGREP_CPP(^yes$,[
+#include <stdio.h>
+#ifdef __GLIBC__
+yes
+#endif
], AC_DEFINE(HAVE_GETHOSTBYNAME_R, GHBN_R_GLIBC,
[Define to flavour of gethostbyname_r]))
;;
@@ -4293,10 +4294,10 @@ case "$erl_xcomp_without_sysroot-$with_ssl" in
SSL_INCLUDE="-I$dir/include"
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS=$SSL_INCLUDE
- AC_EGREP_CPP(yes,[
+ AC_EGREP_CPP(^yes$,[
#include <openssl/opensslv.h>
#if OPENSSL_VERSION_NUMBER >= 0x0090700fL
- yes
+yes
#endif
],[
ssl_found=yes
@@ -4491,10 +4492,10 @@ if test "x$SSL_APP" != "x" ; then
AC_MSG_CHECKING(for OpenSSL kerberos 5 support)
old_CPPFLAGS=$CPPFLAGS
CPPFLAGS=$SSL_INCLUDE
- AC_EGREP_CPP(yes,[
+ AC_EGREP_CPP(^yes$,[
#include <openssl/opensslconf.h>
#ifndef OPENSSL_NO_KRB5
- yes
+yes
#endif
],[
AC_MSG_RESULT([yes])
@@ -4733,11 +4734,11 @@ fi
AC_CHECK_PROGS(JAVAC, $check_javac)
if test -n "$JAVAC"; then
- dnl Make sure it's at least JDK 1.5
+ dnl Make sure it's at least JDK 1.6
AC_CACHE_CHECK(for JDK version 1.6,
ac_cv_prog_javac_ver_1_6,
[ERL_TRY_LINK_JAVA([], [for (String i : args);],
- ac_cv_prog_javac_ver_1_6=yes, ac_cv_prog_javac_ver_1_5=no)])
+ ac_cv_prog_javac_ver_1_6=yes, ac_cv_prog_javac_ver_1_6=no)])
if test $ac_cv_prog_javac_ver_1_6 = no; then
unset -v JAVAC
fi
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 3de94be9ff..4bad8b253c 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -66,34 +66,6 @@
</list>
</warning>
- <p>The NIF concept is officially supported from R14B. NIF source code
- written for earlier experimental versions might need adaption to run on R14B
- or later versions:</p>
- <list>
- <item>No incompatible changes between <em>R14B</em> and R14A.</item>
- <item>Incompatible changes between <em>R14A</em> and R13B04:
- <list>
- <item>Environment argument removed for <c>enif_alloc</c>,
- <c>enif_realloc</c>, <c>enif_free</c>, <c>enif_alloc_binary</c>,
- <c>enif_realloc_binary</c>, <c>enif_release_binary</c>,
- <c>enif_alloc_resource</c>, <c>enif_release_resource</c>,
- <c>enif_is_identical</c> and <c>enif_compare</c>.</item>
- <item>Character encoding argument added to <c>enif_get_atom</c>
- and <c>enif_make_existing_atom</c>.</item>
- <item>Module argument added to <c>enif_open_resource_type</c>
- while changing name spaces of resource types from global to module local.</item>
- </list>
- </item>
- <item>Incompatible changes between <em>R13B04</em> and R13B03:
- <list>
- <item>The function prototypes of the NIFs have changed to expect <c>argc</c> and <c>argv</c>
- arguments. The arity of a NIF is by that no longer limited to 3.</item>
- <item><c>enif_get_data</c> renamed as <c>enif_priv_data</c>.</item>
- <item><c>enif_make_string</c> got a third argument for character encoding.</item>
- </list>
- </item>
- </list>
-
<p>A minimal example of a NIF library can look like this:</p>
<p/>
<code type="none">
@@ -806,6 +778,12 @@ typedef enum {
and return true, or return false if <c>term</c> is not an unsigned integer or is
outside the bounds of type <c>unsigned long</c>.</p></desc>
</func>
+ <func><name><ret>int</ret><nametext>enif_has_pending_exception(ErlNifEnv* env)</nametext></name>
+ <fsummary>Check if an exception has been raised.</fsummary>
+ <desc><p>Return true if a pending exception is associated
+ with the environment <c>env</c>. The only possible exception is currently
+ <c>badarg</c> (see <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>).</p></desc>
+ </func>
<func><name><ret>int</ret><nametext>enif_inspect_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term, ErlNifBinary* bin)</nametext></name>
<fsummary>Inspect the content of a binary</fsummary>
<desc><p>Initialize the structure pointed to by <c>bin</c> with
@@ -898,23 +876,37 @@ typedef enum {
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom(ErlNifEnv* env, const char* name)</nametext></name>
<fsummary>Create an atom term</fsummary>
<desc><p>Create an atom term from the null-terminated C-string <c>name</c>
- with iso-latin-1 encoding.</p></desc>
+ with iso-latin-1 encoding. If the length of <c>name</c> exceeds the maximum length
+ allowed for an atom (255 characters), <c>enif_make_atom</c> invokes
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.
+ </p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)</nametext></name>
<fsummary>Create an atom term</fsummary>
<desc><p>Create an atom term from the string <c>name</c> with length <c>len</c>.
- Null-characters are treated as any other characters.</p></desc>
+ Null-characters are treated as any other characters. If <c>len</c> is greater than the maximum length
+ allowed for an atom (255 characters), <c>enif_make_atom</c> invokes
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.
+ </p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name>
<fsummary>Make a badarg exception.</fsummary>
- <desc><p>Make a badarg exception to be returned from a NIF, and set
- an associated exception reason in <c>env</c>. If
- <c>enif_make_badarg</c> is called, the term it returns <em>must</em>
- be returned from the function that called it. No other return value
- is allowed. Also, the term returned from <c>enif_make_badarg</c> may
- be passed only to
- <seealso marker="#enif_is_exception">enif_is_exception</seealso> and
- not to any other NIF API function.</p></desc>
+ <desc><p>Make a badarg exception to be returned from a NIF, and associate
+ it with the environment <c>env</c>. Once a NIF or any function
+ it calls invokes <c>enif_make_badarg</c>, the runtime ensures that a
+ <c>badarg</c> exception is raised when the NIF returns, even if the NIF
+ attempts to return a non-exception term instead.
+ The return value from <c>enif_make_badarg</c> may only be used as
+ return value from the NIF that invoked it (direct or indirectly)
+ or be passed to
+ <seealso marker="#enif_is_exception">enif_is_exception</seealso>, but
+ not to any other NIF API function.</p>
+ <p>See also: <seealso marker="#enif_has_pending_exception">enif_has_pending_exception</seealso>.
+ </p>
+ <note><p>In earlier versions (older than erts-7.0, OTP 18) the return value
+ from <c>enif_make_badarg</c> had to be returned from the NIF. This
+ requirement is now lifted as the return value from the NIF is ignored
+ if <c>enif_make_badarg</c> has been invoked.</p></note></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)</nametext></name>
<fsummary>Make a binary term.</fsummary>
@@ -931,7 +923,10 @@ typedef enum {
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_double(ErlNifEnv* env, double d)</nametext></name>
<fsummary>Create a floating-point term</fsummary>
- <desc><p>Create a floating-point term from a <c>double</c>.</p></desc>
+ <desc><p>Create a floating-point term from a <c>double</c>. If the <c>double</c> argument is
+ not finite or is NaN, <c>enif_make_double</c> invokes
+ <seealso marker="#enif_make_badarg">enif_make_badarg</seealso>.
+ </p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding encode)</nametext></name>
<fsummary>Create an existing atom term</fsummary>
@@ -939,7 +934,9 @@ typedef enum {
the null-terminated C-string <c>name</c> with encoding
<seealso marker="#ErlNifCharEncoding">encode</seealso>. If the atom
already exists store the term in <c>*atom</c> and return true, otherwise
- return false.</p></desc>
+ return false. If the length of <c>name</c> exceeds the maximum length
+ allowed for an atom (255 characters), <c>enif_make_existing_atom</c>
+ returns false.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)</nametext></name>
<fsummary>Create an existing atom term</fsummary>
@@ -947,7 +944,9 @@ typedef enum {
string <c>name</c> with length <c>len</c> and encoding
<seealso marker="#ErlNifCharEncoding">encode</seealso>. Null-characters
are treated as any other characters. If the atom already exists store the term
- in <c>*atom</c> and return true, otherwise return false.</p></desc>
+ in <c>*atom</c> and return true, otherwise return false. If <c>len</c> is greater
+ than the maximum length allowed for an atom (255 characters),
+ <c>enif_make_existing_atom_len</c> returns false.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_int(ErlNifEnv* env, int i)</nametext></name>
<fsummary>Create an integer term</fsummary>
diff --git a/erts/doc/src/notes.xml b/erts/doc/src/notes.xml
index a2b4ae49a4..35e6e55e72 100644
--- a/erts/doc/src/notes.xml
+++ b/erts/doc/src/notes.xml
@@ -30,6 +30,22 @@
</header>
<p>This document describes the changes made to the ERTS application.</p>
+<section><title>Erts 6.4.1</title>
+
+ <section><title>Fixed Bugs and Malfunctions</title>
+ <list>
+ <item>
+ <p>
+ The VTS mode in Common Test has been modified to use a
+ private version of the Webtool application (ct_webtool).</p>
+ <p>
+ Own Id: OTP-12704 Aux Id: OTP-10922 </p>
+ </item>
+ </list>
+ </section>
+
+</section>
+
<section><title>Erts 6.4</title>
<section><title>Fixed Bugs and Malfunctions</title>
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index bb7b799950..21faf8fbf2 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -562,7 +562,8 @@ void** beam_ops;
Store(term, Dst); \
} while (0)
-#define Move2(src1, dst1, src2, dst2) dst1 = (src1); dst2 = (src2)
+#define Move2(S1, D1, S2, D2) D1 = (S1); D2 = (S2)
+#define Move3(S1, D1, S2, D2, S3, D3) D1 = (S1); D2 = (S2); D3 = (S3)
#define MoveGenDest(src, dstp) \
if ((dstp) == NULL) { r(0) = (src); } else { *(dstp) = src; }
@@ -662,6 +663,9 @@ void** beam_ops;
#define EqualImmed(X, Y, Action) if (X != Y) { Action; }
#define NotEqualImmed(X, Y, Action) if (X == Y) { Action; }
+#define EqualExact(X, Y, Action) if (!EQ(X,Y)) { Action; }
+#define IsLessThan(X, Y, Action) if (CMP_GE(X, Y)) { Action; }
+#define IsGreaterEqual(X, Y, Action) if (CMP_LT(X, Y)) { Action; }
#define IsFloat(Src, Fail) if (is_not_float(Src)) { Fail; }
@@ -1389,7 +1393,39 @@ void process_main(void)
ASSERT(c_p->freason != BADMATCH || is_value(c_p->fvalue));
goto find_func_info;
}
-
+
+#define DO_BIG_ARITH(Func,Arg1,Arg2) \
+ do { \
+ Uint live = Arg(1); \
+ SWAPOUT; \
+ reg[0] = r(0); \
+ reg[live] = (Arg1); \
+ reg[live+1] = (Arg2); \
+ result = (Func)(c_p, reg, live); \
+ r(0) = reg[0]; \
+ SWAPIN; \
+ ERTS_HOLE_CHECK(c_p); \
+ if (is_value(result)) { \
+ StoreBifResult(4,result); \
+ } \
+ goto lb_Cl_error; \
+ } while(0)
+
+ OpCase(i_plus_jIxxd):
+ {
+ Eterm result;
+
+ if (is_both_small(xb(Arg(2)), xb(Arg(3)))) {
+ Sint i = signed_val(xb(Arg(2))) + signed_val(xb(Arg(3)));
+ ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i));
+ if (MY_IS_SSMALL(i)) {
+ result = make_small(i);
+ StoreBifResult(4, result);
+ }
+ }
+ DO_BIG_ARITH(ARITH_FUNC(mixed_plus), xb(Arg(2)), xb(Arg(3)));
+ }
+
OpCase(i_plus_jId):
{
Eterm result;
@@ -1401,12 +1437,26 @@ void process_main(void)
result = make_small(i);
STORE_ARITH_RESULT(result);
}
-
}
arith_func = ARITH_FUNC(mixed_plus);
goto do_big_arith2;
}
+ OpCase(i_minus_jIxxd):
+ {
+ Eterm result;
+
+ if (is_both_small(xb(Arg(2)), xb(Arg(3)))) {
+ Sint i = signed_val(xb(Arg(2))) - signed_val(xb(Arg(3)));
+ ASSERT(MY_IS_SSMALL(i) == IS_SSMALL(i));
+ if (MY_IS_SSMALL(i)) {
+ result = make_small(i);
+ StoreBifResult(4, result);
+ }
+ }
+ DO_BIG_ARITH(ARITH_FUNC(mixed_minus), xb(Arg(2)), xb(Arg(3)));
+ }
+
OpCase(i_minus_jId):
{
Eterm result;
@@ -1499,6 +1549,52 @@ void process_main(void)
Next(2);
}
+ OpCase(move_window3_xxxy): {
+ BeamInstr *next;
+ Eterm xt0, xt1, xt2;
+ Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(3)));
+ PreFetch(4, next);
+ xt0 = xb(Arg(0));
+ xt1 = xb(Arg(1));
+ xt2 = xb(Arg(2));
+ y[0] = xt0;
+ y[1] = xt1;
+ y[2] = xt2;
+ NextPF(4, next);
+ }
+ OpCase(move_window4_xxxxy): {
+ BeamInstr *next;
+ Eterm xt0, xt1, xt2, xt3;
+ Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(4)));
+ PreFetch(5, next);
+ xt0 = xb(Arg(0));
+ xt1 = xb(Arg(1));
+ xt2 = xb(Arg(2));
+ xt3 = xb(Arg(3));
+ y[0] = xt0;
+ y[1] = xt1;
+ y[2] = xt2;
+ y[3] = xt3;
+ NextPF(5, next);
+ }
+ OpCase(move_window5_xxxxxy): {
+ BeamInstr *next;
+ Eterm xt0, xt1, xt2, xt3, xt4;
+ Eterm *y = (Eterm *)(((unsigned char *)E) + (Arg(5)));
+ PreFetch(6, next);
+ xt0 = xb(Arg(0));
+ xt1 = xb(Arg(1));
+ xt2 = xb(Arg(2));
+ xt3 = xb(Arg(3));
+ xt4 = xb(Arg(4));
+ y[0] = xt0;
+ y[1] = xt1;
+ y[2] = xt2;
+ y[3] = xt3;
+ y[4] = xt4;
+ NextPF(6, next);
+ }
+
OpCase(i_move_call_only_fcr): {
r(0) = Arg(1);
}
@@ -2835,6 +2931,19 @@ do { \
goto do_big_arith2;
}
+ OpCase(i_rem_jIxxd):
+ {
+ Eterm result;
+
+ if (xb(Arg(3)) == SMALL_ZERO) {
+ goto badarith;
+ } else if (is_both_small(xb(Arg(2)), xb(Arg(3)))) {
+ result = make_small(signed_val(xb(Arg(2))) % signed_val(xb(Arg(3))));
+ StoreBifResult(4, result);
+ }
+ DO_BIG_ARITH(ARITH_FUNC(int_rem),xb(Arg(2)),xb(Arg(3)));
+ }
+
OpCase(i_rem_jId):
{
Eterm result;
@@ -2850,6 +2959,20 @@ do { \
}
}
+ OpCase(i_band_jIxcd):
+ {
+ Eterm result;
+
+ if (is_both_small(xb(Arg(2)), Arg(3))) {
+ /*
+ * No need to untag -- TAG & TAG == TAG.
+ */
+ result = xb(Arg(2)) & Arg(3);
+ StoreBifResult(4, result);
+ }
+ DO_BIG_ARITH(ARITH_FUNC(band),xb(Arg(2)),Arg(3));
+ }
+
OpCase(i_band_jId):
{
Eterm result;
@@ -2865,6 +2988,8 @@ do { \
goto do_big_arith2;
}
+#undef DO_BIG_ARITH
+
do_big_arith2:
{
Eterm result;
@@ -3516,6 +3641,8 @@ do { \
erts_pre_nif(&env, c_p, (struct erl_module_nif*)I[2]);
reg[0] = r(0);
nif_bif_result = (*fp)(&env, bif_nif_arity, reg);
+ if (env.exception_thrown)
+ nif_bif_result = THE_NON_VALUE;
erts_post_nif(&env);
}
ASSERT(!ERTS_PROC_IS_EXITING(c_p) || is_non_value(nif_bif_result));
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 8d7beb4eb4..282aa71109 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -3172,7 +3172,11 @@ gen_increment_from_minus(LoaderState* stp, GenOpArg Reg, GenOpArg Integer,
static int
negation_is_small(LoaderState* stp, GenOpArg Int)
{
- return Int.type == TAG_i && IS_SSMALL(-Int.val);
+ /* Check for the rare case of overflow in BeamInstr (UWord) -> Sint
+ * Cast to the correct type before using IS_SSMALL (Sint) */
+ return Int.type == TAG_i &&
+ !(Int.val & ~((((BeamInstr)1) << ((sizeof(Sint)*8)-1))-1)) &&
+ IS_SSMALL(-((Sint)Int.val));
}
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index e2f8da38b9..074f864dee 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -419,7 +419,12 @@ type ENVIRONMENT TEMPORARY SYSTEM environment
type PUTENV_STR SYSTEM SYSTEM putenv_string
type PRT_REP_EXIT STANDARD SYSTEM port_report_exit
type SYS_BLOCKING STANDARD SYSTEM sys_blocking
+
++if smp
type SYS_WRITE_BUF TEMPORARY SYSTEM sys_write_buf
++else
+type SYS_WRITE_BUF BINARY SYSTEM sys_write_buf
++endif
+endif
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c
index 5cc0a23dc9..b8ae93fa58 100644
--- a/erts/emulator/beam/erl_bits.c
+++ b/erts/emulator/beam/erl_bits.c
@@ -165,6 +165,26 @@ erts_bs_start_match_2(Process *p, Eterm Binary, Uint Max)
return make_matchstate(ms);
}
+#ifdef DEBUG
+# define CHECK_MATCH_BUFFER(MB) check_match_buffer(MB)
+
+static void check_match_buffer(ErlBinMatchBuffer* mb)
+{
+ Eterm realbin;
+ Uint byteoffs;
+ byte* bytes, bitoffs, bitsz;
+ ProcBin* pb;
+ ERTS_GET_REAL_BIN(mb->orig, realbin, byteoffs, bitoffs, bitsz);
+ bytes = binary_bytes(realbin) + byteoffs;
+ ERTS_ASSERT(mb->base >= bytes && mb->base <= (bytes + binary_size(mb->orig)));
+ pb = (ProcBin *) boxed_val(realbin);
+ if (pb->thing_word == HEADER_PROC_BIN)
+ ERTS_ASSERT(pb->flags == 0);
+}
+#else
+# define CHECK_MATCH_BUFFER(MB)
+#endif
+
Eterm
erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer* mb)
{
@@ -185,6 +205,7 @@ erts_bs_get_integer_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuff
return SMALL_ZERO;
}
+ CHECK_MATCH_BUFFER(mb);
if (mb->size - mb->offset < num_bits) { /* Asked for too many bits. */
return THE_NON_VALUE;
}
@@ -425,6 +446,7 @@ erts_bs_get_binary_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffe
{
ErlSubBin* sb;
+ CHECK_MATCH_BUFFER(mb);
if (mb->size - mb->offset < num_bits) { /* Asked for too many bits. */
return THE_NON_VALUE;
}
@@ -456,6 +478,7 @@ erts_bs_get_float_2(Process *p, Uint num_bits, unsigned flags, ErlBinMatchBuffer
byte* fptr;
FloatDef f;
+ CHECK_MATCH_BUFFER(mb);
if (num_bits == 0) {
f.fd = 0.0;
hp = HeapOnlyAlloc(p, FLOAT_SIZE_OBJECT);
@@ -509,6 +532,8 @@ erts_bs_get_binary_all_2(Process *p, ErlBinMatchBuffer* mb)
{
ErlSubBin* sb;
Uint size;
+
+ CHECK_MATCH_BUFFER(mb);
size = mb->size-mb->offset;
sb = (ErlSubBin *) HeapOnlyAlloc(p, ERL_SUB_BIN_SIZE);
sb->thing_word = HEADER_SUB_BIN;
@@ -1595,6 +1620,7 @@ erts_bs_get_unaligned_uint32(ErlBinMatchBuffer* mb)
byte* LSB;
byte* MSB;
+ CHECK_MATCH_BUFFER(mb);
ASSERT((mb->offset & 7) != 0);
ASSERT(mb->size - mb->offset >= 32);
@@ -1654,6 +1680,8 @@ erts_bs_get_utf8(ErlBinMatchBuffer* mb)
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,9,9,9,9,9,9,9,9
};
+ CHECK_MATCH_BUFFER(mb);
+
if ((remaining_bits = mb->size - mb->offset) < 8) {
return THE_NON_VALUE;
}
@@ -1738,6 +1766,7 @@ erts_bs_get_utf16(ErlBinMatchBuffer* mb, Uint flags)
return THE_NON_VALUE;
}
+ CHECK_MATCH_BUFFER(mb);
/*
* Set up the pointer to the source bytes.
*/
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index a4f1e0d7ee..4f12727044 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -118,6 +118,8 @@ const int etp_big_endian = 1;
#else
const int etp_big_endian = 0;
#endif
+const Eterm etp_the_non_value = THE_NON_VALUE;
+
/*
* Note about VxWorks: All variables must be initialized by executable code,
* not by an initializer. Otherwise a new instance of the emulator will
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 776bbf6719..25caaa4e44 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -128,6 +128,7 @@ void erts_pre_nif(ErlNifEnv* env, Process* p, struct erl_module_nif* mod_nif)
env->heap_frag = NULL;
env->fpe_was_unmasked = erts_block_fpe();
env->tmp_obj_list = NULL;
+ env->exception_thrown = 0;
}
static void pre_nif_noproc(ErlNifEnv* env, struct erl_module_nif* mod_nif)
@@ -736,9 +737,15 @@ Eterm enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term,
Eterm enif_make_badarg(ErlNifEnv* env)
{
+ env->exception_thrown = 1;
BIF_ERROR(env->proc, BADARG);
}
+int enif_has_pending_exception(ErlNifEnv* env)
+{
+ return env->exception_thrown;
+}
+
int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len,
ErlNifCharEncoding encoding)
{
@@ -958,8 +965,12 @@ ERL_NIF_TERM enif_make_uint64(ErlNifEnv* env, ErlNifUInt64 i)
ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d)
{
- Eterm* hp = alloc_heap(env,FLOAT_SIZE_OBJECT);
+ Eterm* hp;
FloatDef f;
+
+ if (!erts_isfinite(d))
+ return enif_make_badarg(env);
+ hp = alloc_heap(env,FLOAT_SIZE_OBJECT);
f.fd = d;
PUT_DOUBLE(f, hp);
return make_float(hp);
@@ -972,6 +983,8 @@ ERL_NIF_TERM enif_make_atom(ErlNifEnv* env, const char* name)
ERL_NIF_TERM enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)
{
+ if (len > MAX_ATOM_CHARACTERS)
+ return enif_make_badarg(env);
return erts_atom_put((byte*)name, len, ERTS_ATOM_ENC_LATIN1, 1);
}
@@ -985,6 +998,8 @@ int enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len,
ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)
{
ASSERT(encoding == ERL_NIF_LATIN1);
+ if (len > MAX_ATOM_CHARACTERS)
+ return 0;
return erts_atom_get(name, len, atom, ERTS_ATOM_ENC_LATIN1);
}
@@ -1748,14 +1763,13 @@ execute_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
ASSERT(ep);
if (ep->fp)
fp = NULL;
- if (is_non_value(result)) {
+ if (is_non_value(result) || env->exception_thrown) {
if (proc->freason != TRAP) {
- ASSERT(proc->freason == BADARG);
return init_nif_sched_data(env, dirty_nif_exception, fp, 0, argc, argv);
} else {
if (ep->fp == NULL)
restore_nif_mfa(proc, ep, 1);
- return result;
+ return THE_NON_VALUE;
}
}
else
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index 9b2b90c82d..c4fdfd4187 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -46,9 +46,10 @@
** remove enif_schedule_dirty_nif, enif_schedule_dirty_nif_finalizer, enif_dirty_nif_finalizer
** add ErlNifEntry options
** add ErlNifFunc flags
+** 2.8: 18.0 add enif_has_pending_exception
*/
#define ERL_NIF_MAJOR_VERSION 2
-#define ERL_NIF_MINOR_VERSION 7
+#define ERL_NIF_MINOR_VERSION 8
/*
* The emulator will refuse to load a nif-lib with a major version
diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h
index 630cefae93..bdcbb32c46 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -156,6 +156,7 @@ ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_next, (ErlNifEnv *env, ErlNifMapIte
ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_prev, (ErlNifEnv *env, ErlNifMapIterator *iter));
ERL_NIF_API_FUNC_DECL(int, enif_map_iterator_get_pair, (ErlNifEnv *env, ErlNifMapIterator *iter, ERL_NIF_TERM *key, ERL_NIF_TERM *value));
ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_schedule_nif,(ErlNifEnv*,const char*,int,ERL_NIF_TERM (*)(ErlNifEnv*,int,const ERL_NIF_TERM[]),int,const ERL_NIF_TERM[]));
+ERL_NIF_API_FUNC_DECL(int, enif_has_pending_exception, (ErlNifEnv *env));
/*
** ADD NEW ENTRIES HERE (before this comment) !!!
@@ -305,6 +306,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_is_on_dirty_scheduler,(ErlNifEnv*));
# define enif_map_iterator_prev ERL_NIF_API_FUNC_MACRO(enif_map_iterator_prev)
# define enif_map_iterator_get_pair ERL_NIF_API_FUNC_MACRO(enif_map_iterator_get_pair)
# define enif_schedule_nif ERL_NIF_API_FUNC_MACRO(enif_schedule_nif)
+# define enif_has_pending_exception ERL_NIF_API_FUNC_MACRO(enif_has_pending_exception)
/*
** ADD NEW ENTRIES HERE (before this comment)
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 6518314e30..00c7b163c2 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -4956,9 +4956,11 @@ wakeup_other_check(ErtsRunQueue *rq, Uint32 flags)
+ ERTS_WAKEUP_OTHER_FIXED_INC);
if (rq->wakeup_other > wakeup_other.limit) {
#ifdef ERTS_DIRTY_SCHEDULERS
- if (ERTS_RUNQ_IX_IS_DIRTY(rq->ix) && rq->waiting)
- wake_dirty_schedulers(rq, 1);
- else
+ if (ERTS_RUNQ_IX_IS_DIRTY(rq->ix)) {
+ if (rq->waiting) {
+ wake_dirty_schedulers(rq, 1);
+ }
+ } else
#endif
{
int empty_rqs =
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index 634fe533d0..40b043d1cc 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -52,6 +52,7 @@ struct enif_environment_t /* ErlNifEnv */
ErlHeapFragment* heap_frag;
int fpe_was_unmasked;
struct enif_tmp_obj_t* tmp_obj_list;
+ int exception_thrown; /* boolean */
};
extern void erts_pre_nif(struct enif_environment_t*, Process*,
struct erl_module_nif*);
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 8cb185cb2b..dec92be40a 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -5559,7 +5559,9 @@ driver_deliver_term(Eterm to, ErlDrvTermData* data, int len)
mess = make_float(hp);
f.fd = *((double *) ptr[0]);
- PUT_DOUBLE(f, hp);
+ if (!erts_isfinite(f.fd))
+ ERTS_DDT_FAIL;
+ PUT_DOUBLE(f, hp);
hp += FLOAT_SIZE_OBJECT;
ptr++;
break;
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 9bdc9cb88d..ece038131e 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -298,10 +298,49 @@ move_jump f c
move_jump f x
move_jump f y
+
+# Movement to and from the stack is common
+# Try to pack as much as we can into one instruction
+
+# Window move
+move_window/5
+move_window/6
+
+# x -> y
+
+move S1=r S2=y | move X1=x Y1=y => move2 S1 S2 X1 Y1
+
+move X1=x Y1=y | move X2=x Y2=y | move X3=x Y3=y | succ(Y1,Y2) | succ(Y2,Y3) => \
+ move_window X1 X2 X3 Y1 Y3
+
+move_window X1=x X2=x X3=x Y1=y Y3=y | move X4=x Y4=y | succ(Y3,Y4) => \
+ move_window X1 X2 X3 X4 Y1 Y4
+
+move_window X1=x X2=x X3=x X4=x Y1=y Y4=y | move X5=x Y5=y | succ(Y4,Y5) => \
+ move_window5 X1 X2 X3 X4 X5 Y1
+
+move_window X1=x X2=x X3=x Y1=y Y3=y => move_window3 X1 X2 X3 Y1
+move_window X1=x X2=x X3=x X4=x Y1=y Y4=y => move_window4 X1 X2 X3 X4 Y1
+
+move_window3 x x x y
+move_window4 x x x x y
+move_window5 x x x x x y
+
move X1=x Y1=y | move X2=x Y2=y => move2 X1 Y1 X2 Y2
move Y1=y X1=x | move Y2=y X2=x => move2 Y1 X1 Y2 X2
move X1=x X2=x | move X3=x X4=x => move2 X1 X2 X3 X4
+move S1=x S2=r | move S3=x S4=x => move2 S1 S2 S3 S4
+move S1=x S2=r | move X1=x Y1=y => move2 S1 S2 X1 Y1
+move S1=y S2=r | move X1=x Y1=y => move2 S1 S2 X1 Y1
+
+move Y1=y X1=x | move S1=r D1=x => move2 Y1 X1 S1 D1
+move S1=r D1=x | move Y1=y X1=x => move2 S1 D1 Y1 X1
+
+move2 X1=x Y1=y X2=x Y2=y | move X3=x Y3=y => move3 X1 Y1 X2 Y2 X3 Y3
+move2 Y1=y X1=x Y2=y X2=x | move Y3=y X3=x => move3 Y1 X1 Y2 X2 Y3 X3
+move2 X1=x X2=x X3=x X4=x | move X5=x X6=x => move3 X1 X2 X3 X4 X5 X6
+
move C=aiq X=x==1 => move_x1 C
move C=aiq X=x==2 => move_x2 C
@@ -313,6 +352,20 @@ move2 x y x y
move2 y x y x
move2 x x x x
+move2 x r x x
+
+move2 x r x y
+move2 r y x y
+move2 y r x y
+
+move2 r x y x
+move2 y x r x
+
+%macro: move3 Move3
+move3 x y x y x y
+move3 y x y x y x
+move3 x x x x x x
+
# The compiler almost never generates a "move Literal y(Y)" instruction,
# so let's cheat if we encounter one.
move S=n D=y => init D
@@ -392,14 +445,59 @@ i_is_ne_exact_literal x f c
i_is_ne_exact_literal y f c
#
+# Common Compare Specializations
+# We don't do all of them since we want
+# to keep the instruction set small-ish
+#
+
+is_eq_exact Lbl S1=xy S2=r => is_eq_exact Lbl S2 S1
+is_eq_exact Lbl S1=rx S2=xy => i_is_eq_exact_spec Lbl S1 S2
+%macro: i_is_eq_exact_spec EqualExact -fail_action
+
+i_is_eq_exact_spec f x x
+i_is_eq_exact_spec f x y
+i_is_eq_exact_spec f r x
+i_is_eq_exact_spec f r y
+%cold
+i_is_eq_exact_spec f r r
+%hot
+
+is_lt Lbl S1=rxc S2=rxc => i_is_lt_spec Lbl S1 S2
+
+%macro: i_is_lt_spec IsLessThan -fail_action
+
+i_is_lt_spec f x x
+i_is_lt_spec f x r
+i_is_lt_spec f x c
+i_is_lt_spec f r x
+i_is_lt_spec f r c
+i_is_lt_spec f c x
+i_is_lt_spec f c r
+%cold
+i_is_lt_spec f r r
+i_is_lt_spec f c c
+%hot
+
+is_ge Lbl S1=xc S2=xc => i_is_ge_spec Lbl S1 S2
+
+%macro: i_is_ge_spec IsGreaterEqual -fail_action
+
+i_is_ge_spec f x x
+i_is_ge_spec f x c
+i_is_ge_spec f c x
+%cold
+i_is_ge_spec f c c
+%hot
+
+#
# All other comparisons.
#
is_eq_exact Lbl S1 S2 => i_fetch S1 S2 | i_is_eq_exact Lbl
is_ne_exact Lbl S1 S2 => i_fetch S1 S2 | i_is_ne_exact Lbl
-is_ge Lbl S1 S2 => i_fetch S1 S2 | i_is_ge Lbl
is_lt Lbl S1 S2 => i_fetch S1 S2 | i_is_lt Lbl
+is_ge Lbl S1 S2 => i_fetch S1 S2 | i_is_ge Lbl
is_eq Lbl S1 S2 => i_fetch S1 S2 | i_is_eq Lbl
is_ne Lbl S1 S2 => i_fetch S1 S2 | i_is_ne Lbl
@@ -493,7 +591,6 @@ put_list s s d
%hot
%macro: i_fetch FetchArgs -pack
-i_fetch c c
i_fetch c r
i_fetch c x
i_fetch c y
@@ -510,6 +607,7 @@ i_fetch y x
i_fetch y y
%cold
+i_fetch c c
i_fetch s s
%hot
@@ -1562,17 +1660,21 @@ gc_bif2 p Live u$bif:erlang:sminus/2 Reg=d Int=i Dst | \
# GCing arithmetic instructions.
#
+gc_bif2 Fail I u$bif:erlang:splus/2 S1=x S2=x Dst=d => i_plus Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:splus/2 S1 S2 Dst=d => i_fetch S1 S2 | i_plus Fail I Dst
+gc_bif2 Fail I u$bif:erlang:sminus/2 S1=x S2=x Dst=d => i_minus Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:sminus/2 S1 S2 Dst=d => i_fetch S1 S2 | i_minus Fail I Dst
gc_bif2 Fail I u$bif:erlang:stimes/2 S1 S2 Dst=d => i_fetch S1 S2 | i_times Fail I Dst
gc_bif2 Fail I u$bif:erlang:div/2 S1 S2 Dst=d => i_fetch S1 S2 | i_m_div Fail I Dst
gc_bif2 Fail I u$bif:erlang:intdiv/2 S1 S2 Dst=d => i_fetch S1 S2 | i_int_div Fail I Dst
+gc_bif2 Fail I u$bif:erlang:rem/2 S1=x S2=x Dst=d => i_rem Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:rem/2 S1 S2 Dst=d => i_fetch S1 S2 | i_rem Fail I Dst
gc_bif2 Fail I u$bif:erlang:bsl/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bsl Fail I Dst
gc_bif2 Fail I u$bif:erlang:bsr/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bsr Fail I Dst
+gc_bif2 Fail I u$bif:erlang:band/2 S1=x S2=c Dst=d => i_band Fail I S1 S2 Dst
gc_bif2 Fail I u$bif:erlang:band/2 S1 S2 Dst=d => i_fetch S1 S2 | i_band Fail I Dst
gc_bif2 Fail I u$bif:erlang:bor/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bor Fail I Dst
gc_bif2 Fail I u$bif:erlang:bxor/2 S1 S2 Dst=d => i_fetch S1 S2 | i_bxor Fail I Dst
@@ -1586,16 +1688,20 @@ i_increment r I I d
i_increment x I I d
i_increment y I I d
+i_plus j I x x d
i_plus j I d
+i_minus j I x x d
i_minus j I d
i_times j I d
i_m_div j I d
i_int_div j I d
+i_rem j I x x d
i_rem j I d
i_bsl j I d
i_bsr j I d
+i_band j I x c d
i_band j I d
i_bor j I d
i_bxor j I d
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index ae62a7a708..8f6335d5dd 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -2920,16 +2920,16 @@ Sint cmp(Eterm a, Eterm b)
#if HALFWORD_HEAP
static Sint erts_cmp_compound_rel_opt(Eterm a, Eterm* a_base,
- Eterm b, Eterm* b_base,
- int exact, int eq_only);
+ Eterm b, Eterm* b_base,
+ int exact, int eq_only);
#else
static Sint erts_cmp_compound(Eterm a, Eterm b, int exact, int eq_only);
#endif
#if HALFWORD_HEAP
-Sint erts_cmp(Eterm a, Eterm* a_base,
- Eterm b, Eterm* b_base,
- int exact, int eq_only)
+Sint erts_cmp_rel_opt(Eterm a, Eterm* a_base,
+ Eterm b, Eterm* b_base,
+ int exact, int eq_only)
#else
Sint erts_cmp(Eterm a, Eterm b, int exact, int eq_only)
#endif
@@ -2938,9 +2938,14 @@ Sint erts_cmp(Eterm a, Eterm b, int exact, int eq_only)
return cmp_atoms(a, b);
} else if (is_both_small(a, b)) {
return (signed_val(a) - signed_val(b));
+ } else if (is_float_rel(a, a_base) && is_float_rel(b, b_base)) {
+ FloatDef af, bf;
+ GET_DOUBLE_REL(a, af, a_base);
+ GET_DOUBLE_REL(b, bf, b_base);
+ return float_comp(af.fd, bf.fd);
}
#if HALFWORD_HEAP
- return erts_cmp_compound(a,a_base,b,b_base,exact,eq_only);
+ return erts_cmp_compound_rel_opt(a,a_base,b,b_base,exact,eq_only);
#else
return erts_cmp_compound(a,b,exact,eq_only);
#endif
@@ -2952,8 +2957,9 @@ Sint erts_cmp(Eterm a, Eterm b, int exact, int eq_only)
* exact = 0 -> arith-based compare
*/
#if HALFWORD_HEAP
-static Sint erts_cmp_compound_rel_opt(Eterm a, Eterm* a_base, Eterm b, Eterm* b_base,
- int exact, int eq_only)
+static Sint erts_cmp_compound_rel_opt(Eterm a, Eterm* a_base,
+ Eterm b, Eterm* b_base,
+ int exact, int eq_only)
#else
static Sint erts_cmp_compound(Eterm a, Eterm b, int exact, int eq_only)
#endif
diff --git a/erts/emulator/hipe/hipe_amd64_bifs.m4 b/erts/emulator/hipe/hipe_amd64_bifs.m4
index 7d94aa05b3..74cb9112ce 100644
--- a/erts/emulator/hipe/hipe_amd64_bifs.m4
+++ b/erts/emulator/hipe/hipe_amd64_bifs.m4
@@ -159,37 +159,36 @@ define(standard_bif_interface_4,
`
#ifndef HAVE_$1
#`define' HAVE_$1
- TEXT
- .align 4
- GLOBAL(ASYM($1))
+ TEXT
+ .align 4
+ GLOBAL(ASYM($1))
ASYM($1):
- /* set up the parameters */
- movq P, %rdi
- NBIF_ARG(%rsi,4,0)
- NBIF_ARG(%rdx,4,1)
- NBIF_ARG(%rcx,4,2)
- NBIF_ARG(%r8,4,3)
-
- /* make the call on the C stack */
- SWITCH_ERLANG_TO_C
- pushq %r8
- pushq %rcx
- pushq %rdx
- pushq %rsi
- movq %rsp, %rsi /* Eterm* BIF__ARGS */
- sub $(8), %rsp /* stack frame 16-byte alignment */
- CALL_BIF($2)
- add $(4*8 + 8), %rsp
- TEST_GOT_MBUF
- SWITCH_C_TO_ERLANG
-
- /* throw exception if failure, otherwise return */
- TEST_GOT_EXN
- jz nbif_4_simple_exception
- NBIF_RET(4)
- HANDLE_GOT_MBUF(4)
- SET_SIZE(ASYM($1))
- TYPE_FUNCTION(ASYM($1))
+ /* set up the parameters */
+ movq P, %rdi
+ NBIF_ARG(%rsi,4,0)
+ NBIF_ARG(%rdx,4,1)
+ NBIF_ARG(%rcx,4,2)
+ NBIF_ARG(%r8,4,3)
+
+ /* make the call on the C stack */
+ SWITCH_ERLANG_TO_C
+ pushq %r8
+ pushq %rcx
+ pushq %rdx
+ pushq %rsi
+ movq %rsp, %rsi /* Eterm* BIF__ARGS */
+ CALL_BIF($2)
+ add $(4*8), %rsp
+ TEST_GOT_MBUF
+ SWITCH_C_TO_ERLANG
+
+ /* throw exception if failure, otherwise return */
+ TEST_GOT_EXN
+ jz nbif_4_simple_exception
+ NBIF_RET(4)
+ HANDLE_GOT_MBUF(4)
+ SET_SIZE(ASYM($1))
+ TYPE_FUNCTION(ASYM($1))
#endif')
define(standard_bif_interface_0,
diff --git a/erts/emulator/hipe/hipe_arm_asm.m4 b/erts/emulator/hipe/hipe_arm_asm.m4
index b2e3f83d1e..ca6aef2f8d 100644
--- a/erts/emulator/hipe/hipe_arm_asm.m4
+++ b/erts/emulator/hipe/hipe_arm_asm.m4
@@ -163,6 +163,10 @@ define(NBIF_ARG,`ifelse(eval($3 >= NR_ARG_REGS),0,`NBIF_REG_ARG($1,$3)',`NBIF_ST
`/* #define NBIF_ARG_3_0 'NBIF_ARG(r1,3,0)` */'
`/* #define NBIF_ARG_3_1 'NBIF_ARG(r2,3,1)` */'
`/* #define NBIF_ARG_3_2 'NBIF_ARG(r3,3,2)` */'
+`/* #define NBIF_ARG_4_0 'NBIF_ARG(r1,4,0)` */'
+`/* #define NBIF_ARG_4_1 'NBIF_ARG(r2,4,1)` */'
+`/* #define NBIF_ARG_4_2 'NBIF_ARG(r3,4,2)` */'
+`/* #define NBIF_ARG_4_3 'NBIF_ARG(r4,4,3)` */'
`/* #define NBIF_ARG_5_0 'NBIF_ARG(r1,5,0)` */'
`/* #define NBIF_ARG_5_1 'NBIF_ARG(r2,5,1)` */'
`/* #define NBIF_ARG_5_2 'NBIF_ARG(r3,5,2)` */'
@@ -186,6 +190,7 @@ define(NBIF_RET,`NBIF_RET_N(eval(RET_POP($1)))')dnl
`/* #define NBIF_RET_1 'NBIF_RET(1)` */'
`/* #define NBIF_RET_2 'NBIF_RET(2)` */'
`/* #define NBIF_RET_3 'NBIF_RET(3)` */'
+`/* #define NBIF_RET_4 'NBIF_RET(4)` */'
`/* #define NBIF_RET_5 'NBIF_RET(5)` */'
dnl
diff --git a/erts/emulator/hipe/hipe_arm_bifs.m4 b/erts/emulator/hipe/hipe_arm_bifs.m4
index 884240be9c..6abc7545e0 100644
--- a/erts/emulator/hipe/hipe_arm_bifs.m4
+++ b/erts/emulator/hipe/hipe_arm_bifs.m4
@@ -42,9 +42,10 @@ define(TEST_GOT_MBUF,`ldr r1, [P, #P_MBUF] /* `TEST_GOT_MBUF' */
* standard_bif_interface_1(nbif_name, cbif_name)
* standard_bif_interface_2(nbif_name, cbif_name)
* standard_bif_interface_3(nbif_name, cbif_name)
+ * standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 1-3 parameters and
+ * Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
@@ -134,6 +135,39 @@ $1:
.type $1, %function
#endif')
+define(standard_bif_interface_4,
+`
+#ifndef HAVE_$1
+#`define' HAVE_$1
+ .global $1
+$1:
+ /* Set up C argument registers. */
+ mov r0, P
+ NBIF_ARG(r1,4,0)
+ NBIF_ARG(r2,4,1)
+ NBIF_ARG(r3,4,2)
+ NBIF_ARG(r4,4,3)
+
+ /* Save caller-save registers and call the C function. */
+ SAVE_CONTEXT_BIF
+ str r1, [r0, #P_ARG0] /* Store BIF__ARGS in def_arg_reg[] */
+ str r2, [r0, #P_ARG1]
+ str r3, [r0, #P_ARG2]
+ str r4, [r0, #P_ARG3]
+ add r1, r0, #P_ARG0
+ CALL_BIF($2)
+ TEST_GOT_MBUF(4)
+
+ /* Restore registers. Check for exception. */
+ cmp r0, #THE_NON_VALUE
+ RESTORE_CONTEXT_BIF
+ beq nbif_4_simple_exception
+ NBIF_RET(4)
+ .ltorg
+ .size $1, .-$1
+ .type $1, %function
+#endif')
+
define(standard_bif_interface_0,
`
#ifndef HAVE_$1
diff --git a/erts/emulator/hipe/hipe_arm_glue.S b/erts/emulator/hipe/hipe_arm_glue.S
index e7ff267606..edcabfd7a4 100644
--- a/erts/emulator/hipe/hipe_arm_glue.S
+++ b/erts/emulator/hipe/hipe_arm_glue.S
@@ -330,6 +330,12 @@ nbif_2_gc_after_bif:
.type nbif_3_gc_after_bif, %function
nbif_3_gc_after_bif:
mov r1, #3
+ b .gc_after_bif
+
+ .global nbif_4_gc_after_bif
+ .type nbif_4_gc_after_bif, %function
+nbif_4_gc_after_bif:
+ mov r1, #4
/*FALLTHROUGH*/
.gc_after_bif:
str r1, [P, #P_NARITY]
@@ -376,6 +382,12 @@ nbif_2_simple_exception:
.type nbif_3_simple_exception, %function
nbif_3_simple_exception:
mov r1, #3
+ b .nbif_simple_exception
+
+ .global nbif_4_simple_exception
+ .type nbif_4_simple_exception, %function
+nbif_4_simple_exception:
+ mov r1, #4
/*FALLTHROUGH*/
.nbif_simple_exception:
ldr r0, [P, #P_FREASON]
diff --git a/erts/emulator/hipe/hipe_bif0.c b/erts/emulator/hipe/hipe_bif0.c
index 6c1de05a4c..099f4f90de 100644
--- a/erts/emulator/hipe/hipe_bif0.c
+++ b/erts/emulator/hipe/hipe_bif0.c
@@ -910,6 +910,13 @@ void hipe_emulate_fpe(Process* p)
}
#endif
+void hipe_emasculate_binary(Eterm bin)
+{
+ ProcBin* pb = (ProcBin *) boxed_val(bin);
+ ASSERT(pb->thing_word == HEADER_PROC_BIN);
+ ASSERT(pb->flags != 0);
+ erts_emasculate_writable_binary(pb);
+}
/*
* args: Module, {Uniq, Index, BeamAddress}
diff --git a/erts/emulator/hipe/hipe_bif0.tab b/erts/emulator/hipe/hipe_bif0.tab
index d715a0914b..a3e04802df 100644
--- a/erts/emulator/hipe/hipe_bif0.tab
+++ b/erts/emulator/hipe/hipe_bif0.tab
@@ -140,4 +140,5 @@ atom bs_get_utf16
atom bs_validate_unicode
atom bs_validate_unicode_retract
atom emulate_fpe
+atom emasculate_binary
diff --git a/erts/emulator/hipe/hipe_bif_list.m4 b/erts/emulator/hipe/hipe_bif_list.m4
index 96a849621f..370061bca1 100644
--- a/erts/emulator/hipe/hipe_bif_list.m4
+++ b/erts/emulator/hipe/hipe_bif_list.m4
@@ -250,6 +250,8 @@ gc_bif_interface_0(nbif_check_get_msg, hipe_check_get_msg)
nocons_nofail_primop_interface_0(nbif_emulate_fpe, hipe_emulate_fpe)
#endif
+noproc_primop_interface_1(nbif_emasculate_binary, hipe_emasculate_binary)
+
/*
* SMP-specific stuff
*/
diff --git a/erts/emulator/hipe/hipe_native_bif.h b/erts/emulator/hipe/hipe_native_bif.h
index 3f460a5a5c..574e20e2e4 100644
--- a/erts/emulator/hipe/hipe_native_bif.h
+++ b/erts/emulator/hipe/hipe_native_bif.h
@@ -98,6 +98,9 @@ AEXTERN(void,nbif_emulate_fpe,(Process*));
void hipe_emulate_fpe(Process*);
#endif
+AEXTERN(void,nbif_emasculate_binary,(Eterm));
+void hipe_emasculate_binary(Eterm);
+
/*
* Stuff that is different in SMP and non-SMP.
*/
diff --git a/erts/emulator/hipe/hipe_ppc_glue.S b/erts/emulator/hipe/hipe_ppc_glue.S
index b07f4bc9c8..109289116b 100644
--- a/erts/emulator/hipe/hipe_ppc_glue.S
+++ b/erts/emulator/hipe/hipe_ppc_glue.S
@@ -510,22 +510,26 @@ CSYM(nbif_4_gc_after_bif):
CSYM(nbif_0_simple_exception):
li r4, 0
b .nbif_simple_exception
+
OPD(nbif_1_simple_exception)
GLOBAL(CSYM(nbif_1_simple_exception))
CSYM(nbif_1_simple_exception):
li r4, 1
b .nbif_simple_exception
+
OPD(nbif_2_simple_exception)
GLOBAL(CSYM(nbif_2_simple_exception))
CSYM(nbif_2_simple_exception):
li r4, 2
b .nbif_simple_exception
+
OPD(nbif_3_simple_exception)
GLOBAL(CSYM(nbif_3_simple_exception))
CSYM(nbif_3_simple_exception):
li r4, 3
b .nbif_simple_exception
- OPD(nbif_3_simple_exception)
+
+ OPD(nbif_4_simple_exception)
GLOBAL(CSYM(nbif_4_simple_exception))
CSYM(nbif_4_simple_exception):
li r4, 4
diff --git a/erts/emulator/hipe/hipe_primops.h b/erts/emulator/hipe/hipe_primops.h
index 52b4681cfe..236f6d0a29 100644
--- a/erts/emulator/hipe/hipe_primops.h
+++ b/erts/emulator/hipe/hipe_primops.h
@@ -80,6 +80,7 @@ PRIMOP_LIST(am_fclearerror_error, &nbif_fclearerror_error)
#ifdef NO_FPE_SIGNALS
PRIMOP_LIST(am_emulate_fpe, &nbif_emulate_fpe)
#endif
+PRIMOP_LIST(am_emasculate_binary, &nbif_emasculate_binary)
PRIMOP_LIST(am_debug_native_called, &nbif_hipe_bifs_debug_native_called)
#if defined(__sparc__)
diff --git a/erts/emulator/hipe/hipe_sparc_bifs.m4 b/erts/emulator/hipe/hipe_sparc_bifs.m4
index 8dfb28c8e0..1d0ff8c16e 100644
--- a/erts/emulator/hipe/hipe_sparc_bifs.m4
+++ b/erts/emulator/hipe/hipe_sparc_bifs.m4
@@ -54,7 +54,7 @@ define(HANDLE_GOT_MBUF,`
* standard_bif_interface_1(nbif_name, cbif_name)
* standard_bif_interface_2(nbif_name, cbif_name)
* standard_bif_interface_3(nbif_name, cbif_name)
- * standard_bif_interface_3(nbif_name, cbif_name)
+ * standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
* Generate native interface for a BIF with 0-4 parameters and
diff --git a/erts/emulator/hipe/hipe_x86_bifs.m4 b/erts/emulator/hipe/hipe_x86_bifs.m4
index b0064ee628..bf549c90e4 100644
--- a/erts/emulator/hipe/hipe_x86_bifs.m4
+++ b/erts/emulator/hipe/hipe_x86_bifs.m4
@@ -51,7 +51,7 @@ define(HANDLE_GOT_MBUF,`
* standard_bif_interface_4(nbif_name, cbif_name)
* standard_bif_interface_0(nbif_name, cbif_name)
*
- * Generate native interface for a BIF with 0-3 parameters and
+ * Generate native interface for a BIF with 0-4 parameters and
* standard failure mode.
*/
define(standard_bif_interface_1,
diff --git a/erts/emulator/sys/ose/erl_ose_sys.h b/erts/emulator/sys/ose/erl_ose_sys.h
index cd66d95c26..f6526a4714 100644
--- a/erts/emulator/sys/ose/erl_ose_sys.h
+++ b/erts/emulator/sys/ose/erl_ose_sys.h
@@ -112,6 +112,8 @@ extern clock_t sys_times(SysTimes *buffer);
/* No use in having other resolutions than 1 Ms. */
#define SYS_CLOCK_RESOLUTION 1
+#define erts_isfinite finite
+
#ifdef NO_FPE_SIGNALS
#define erts_get_current_fp_exception() NULL
diff --git a/erts/emulator/sys/unix/erl_unix_sys.h b/erts/emulator/sys/unix/erl_unix_sys.h
index 8fc5a3ca49..94adcc00c8 100644
--- a/erts/emulator/sys/unix/erl_unix_sys.h
+++ b/erts/emulator/sys/unix/erl_unix_sys.h
@@ -338,6 +338,8 @@ extern void sys_stop_cat(void);
# define HAVE_ISFINITE
#endif
+#define erts_isfinite isfinite
+
#ifdef NO_FPE_SIGNALS
#define erts_get_current_fp_exception() NULL
diff --git a/erts/emulator/sys/win32/erl_win_sys.h b/erts/emulator/sys/win32/erl_win_sys.h
index 5181d6b584..714e7357d4 100644
--- a/erts/emulator/sys/win32/erl_win_sys.h
+++ b/erts/emulator/sys/win32/erl_win_sys.h
@@ -267,6 +267,8 @@ extern volatile int erl_fp_exception;
int _finite(double x);
#endif
+#define erts_isfinite _finite
+
/*#define NO_FPE_SIGNALS*/
#define erts_get_current_fp_exception() NULL
#define __ERTS_FP_CHECK_INIT(fpexnp) do {} while (0)
diff --git a/erts/emulator/test/beam_literals_SUITE.erl b/erts/emulator/test/beam_literals_SUITE.erl
index 85236e4203..9ceb393034 100644
--- a/erts/emulator/test/beam_literals_SUITE.erl
+++ b/erts/emulator/test/beam_literals_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. 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
@@ -226,10 +226,11 @@ literal_type_tests(Config) when is_list(Config) ->
%% Generate an Erlang module with all different type of type tests.
?line Tests = make_test([{T, L} || T <- type_tests(), L <- literals()]),
?line Mod = literal_test,
- ?line Func = {function, 0, test, 0, [{clause,0,[],[],Tests}]},
- ?line Form = [{attribute,0,module,Mod},
- {attribute,0,compile,export_all},
- Func, {eof,0}],
+ Anno = erl_anno:new(0),
+ Func = {function, Anno, test, 0, [{clause,Anno,[],[],Tests}]},
+ Form = [{attribute,Anno,module,Mod},
+ {attribute,Anno,compile,export_all},
+ Func, {eof,Anno}],
%% Print generated code for inspection.
?line lists:foreach(fun (F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Form),
@@ -261,7 +262,8 @@ test(T, L) ->
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
{value,Val,_Bs} = erl_eval:exprs(E, []),
- {match,0,{atom,0,Val},hd(E)}.
+ Anno = erl_anno:new(0),
+ {match,Anno,{atom,Anno,Val},hd(E)}.
test(T, A, L) ->
S = lists:flatten(io_lib:format("begin io:format(\"~~p~n\", [{~p,~p,~p}]), if ~w(~w, ~w) -> true; true -> false end end. ",
@@ -269,7 +271,8 @@ test(T, A, L) ->
{ok,Toks,_Line} = erl_scan:string(S),
{ok,E} = erl_parse:parse_exprs(Toks),
{value,Val,_Bs} = erl_eval:exprs(E, []),
- {match,0,{atom,0,Val},hd(E)}.
+ Anno = erl_anno:new(0),
+ {match,Anno,{atom,Anno,Val},hd(E)}.
literals() ->
[42,
diff --git a/erts/emulator/test/code_parallel_load_SUITE.erl b/erts/emulator/test/code_parallel_load_SUITE.erl
index 428f1242ab..bcec8fa640 100644
--- a/erts/emulator/test/code_parallel_load_SUITE.erl
+++ b/erts/emulator/test/code_parallel_load_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2012-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2012-2014. 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
@@ -190,13 +190,15 @@ handle_cpc_responses(N, Tag, Module) ->
generate(Module, Attributes, FunStrings) ->
FunForms = function_forms(FunStrings),
Forms = [
- {attribute,1,module,Module},
- {attribute,2,export,[FA || {FA,_} <- FunForms]}
- ] ++ [{attribute, 3, A, V}|| {A, V} <- Attributes] ++
+ {attribute,a(1),module,Module},
+ {attribute,a(2),export,[FA || {FA,_} <- FunForms]}
+ ] ++ [{attribute, a(3), A, V}|| {A, V} <- Attributes] ++
[ Function || {_, Function} <- FunForms],
{ok, Module, Bin} = compile:forms(Forms),
Bin.
+a(L) ->
+ erl_anno:new(L).
function_forms([]) -> [];
function_forms([S|Ss]) ->
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index b0624fb8c1..502ada95a1 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -39,7 +39,8 @@
get_length/1, make_atom/1, make_string/1, reverse_list_test/1,
otp_9828/1,
otp_9668/1, consume_timeslice/1, dirty_nif/1, dirty_nif_send/1,
- dirty_nif_exception/1, nif_schedule/1
+ dirty_nif_exception/1, nif_schedule/1,
+ nif_exception/1, nif_nan_and_inf/1, nif_atom_too_long/1
]).
-export([many_args_100/100]).
@@ -68,7 +69,8 @@ all() ->
make_string,reverse_list_test,
otp_9828,
otp_9668, consume_timeslice,
- nif_schedule, dirty_nif, dirty_nif_send, dirty_nif_exception
+ nif_schedule, dirty_nif, dirty_nif_send, dirty_nif_exception,
+ nif_exception, nif_nan_and_inf, nif_atom_too_long
].
groups() ->
@@ -1595,11 +1597,27 @@ dirty_nif_exception(Config) when is_list(Config) ->
N when is_integer(N) ->
ensure_lib_loaded(Config),
try
- call_dirty_nif_exception(),
+ %% this checks that the expected exception
+ %% occurs when the NIF returns the result
+ %% of enif_make_badarg directly
+ call_dirty_nif_exception(1),
?t:fail(expected_badarg)
catch
error:badarg ->
- [{?MODULE,call_dirty_nif_exception,[],_}|_] =
+ [{?MODULE,call_dirty_nif_exception,[1],_}|_] =
+ erlang:get_stacktrace(),
+ ok
+ end,
+ try
+ %% this checks that the expected exception
+ %% occurs when the NIF calls enif_make_badarg
+ %% at some point but then returns a value that
+ %% isn't an exception
+ call_dirty_nif_exception(0),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ [{?MODULE,call_dirty_nif_exception,[0],_}|_] =
erlang:get_stacktrace(),
ok
end
@@ -1608,6 +1626,57 @@ dirty_nif_exception(Config) when is_list(Config) ->
{skipped,"No dirty scheduler support"}
end.
+nif_exception(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+ try
+ call_nif_exception(),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end.
+
+nif_nan_and_inf(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+ try
+ call_nif_nan_or_inf(nan),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end,
+ try
+ call_nif_nan_or_inf(inf),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end,
+ try
+ call_nif_nan_or_inf(tuple),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end.
+
+nif_atom_too_long(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+ try
+ call_nif_atom_too_long(all),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end,
+ try
+ call_nif_atom_too_long(len),
+ ?t:fail(expected_badarg)
+ catch
+ error:badarg ->
+ ok
+ end.
+
next_msg(_Pid) ->
receive
M -> M
@@ -1741,8 +1810,11 @@ consume_timeslice_nif(_,_) -> ?nif_stub.
call_nif_schedule(_,_) -> ?nif_stub.
call_dirty_nif(_,_,_) -> ?nif_stub.
send_from_dirty_nif(_) -> ?nif_stub.
-call_dirty_nif_exception() -> ?nif_stub.
+call_dirty_nif_exception(_) -> ?nif_stub.
call_dirty_nif_zero_args() -> ?nif_stub.
+call_nif_exception() -> ?nif_stub.
+call_nif_nan_or_inf(_) -> ?nif_stub.
+call_nif_atom_too_long(_) -> ?nif_stub.
%% maps
is_map_nif(_) -> ?nif_stub.
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 5a3be84825..3cc9f51ef8 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -380,7 +380,8 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ErlNifSInt64 sint64;
ErlNifUInt64 uint64;
double d;
- ERL_NIF_TERM atom, ref1, ref2;
+ ERL_NIF_TERM atom, ref1, ref2, term;
+ size_t len;
sint = INT_MIN;
do {
@@ -502,6 +503,7 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
goto error;
}
}
+
ref1 = enif_make_ref(env);
ref2 = enif_make_ref(env);
if (!enif_is_ref(env,ref1) || !enif_is_ref(env,ref2)
@@ -890,6 +892,7 @@ static ERL_NIF_TERM check_is_exception(ErlNifEnv* env, int argc, const ERL_NIF_T
ERL_NIF_TERM badarg = enif_make_badarg(env);
if (enif_is_exception(env, error_atom)) return error_atom;
if (!enif_is_exception(env, badarg)) return error_atom;
+ if (!enif_has_pending_exception(env)) return error_atom;
return badarg;
}
@@ -1608,16 +1611,26 @@ static ERL_NIF_TERM send_from_dirty_nif(ErlNifEnv* env, int argc, const ERL_NIF_
static ERL_NIF_TERM call_dirty_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
switch (argc) {
- case 0: {
+ case 1: {
ERL_NIF_TERM args[255];
int i;
- for (i = 0; i < 255; i++)
+ args[0] = argv[0];
+ for (i = 1; i < 255; i++)
args[i] = enif_make_int(env, i);
return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
call_dirty_nif_exception, 255, argv);
}
- case 1:
- return enif_make_badarg(env);
+ case 2: {
+ int return_badarg_directly;
+ enif_get_int(env, argv[0], &return_badarg_directly);
+ assert(return_badarg_directly == 1 || return_badarg_directly == 0);
+ if (return_badarg_directly)
+ return enif_make_badarg(env);
+ else {
+ /* ignore return value */ enif_make_badarg(env);
+ return enif_make_atom(env, "ok");
+ }
+ }
default:
return enif_schedule_nif(env, "call_dirty_nif_exception", ERL_NIF_DIRTY_JOB_CPU_BOUND,
call_dirty_nif_exception, argc-1, argv);
@@ -1637,6 +1650,82 @@ static ERL_NIF_TERM call_dirty_nif_zero_args(ErlNifEnv* env, int argc, const ERL
}
#endif
+/*
+ * Call enif_make_badarg, but don't return its return value. Instead,
+ * return ok. Result should still be a badarg exception for the erlang
+ * caller.
+ */
+static ERL_NIF_TERM call_nif_exception(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ /* ignore return value */ enif_make_badarg(env);
+ return enif_make_atom(env, "ok");
+}
+
+#if !defined(NAN) || !defined(INFINITY)
+double zero(void)
+{
+ return 0.0;
+}
+#endif
+
+static ERL_NIF_TERM call_nif_nan_or_inf(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ double val;
+ char arg[6];
+ ERL_NIF_TERM res;
+
+ assert(argc == 1);
+ enif_get_atom(env, argv[0], arg, sizeof arg, ERL_NIF_LATIN1);
+ if (strcmp(arg, "nan") == 0) {
+ /* Verify that enif_make_double raises a badarg for NaN */
+#ifdef NAN
+ val = NAN;
+#else
+ val = 0.0/zero();
+#endif
+ } else {
+ /* Verify that enif_make_double raises a badarg for NaN and infinity */
+#ifdef INFINITY
+ val = INFINITY;
+#else
+ val = 1.0/zero();
+#endif
+ }
+ res = enif_make_double(env, val);
+ assert(enif_is_exception(env, res));
+ assert(enif_has_pending_exception(env));
+ if (strcmp(arg, "tuple") == 0) {
+ return enif_make_tuple2(env, argv[0], res);
+ } else {
+ return res;
+ }
+}
+
+static ERL_NIF_TERM call_nif_atom_too_long(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ char str[257];
+ char arg[4];
+ size_t len;
+ int i;
+ ERL_NIF_TERM res;
+
+ assert(argc == 1);
+ enif_get_atom(env, argv[0], arg, sizeof arg, ERL_NIF_LATIN1);
+ /* Verify that creating an atom from a string that's too long results in a badarg */
+ for (i = 0; i < sizeof str; ++i) {
+ str[i] = 'a';
+ }
+ str[256] = '\0';
+ if (strcmp(arg, "len") == 0) {
+ len = strlen(str);
+ res = enif_make_atom_len(env, str, len);
+ } else {
+ res = enif_make_atom(env, str);
+ }
+ assert(enif_is_exception(env, res));
+ return res;
+}
+
static ERL_NIF_TERM is_map_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
return enif_make_int(env, enif_is_map(env,argv[0]));
@@ -1821,9 +1910,12 @@ static ErlNifFunc nif_funcs[] =
#ifdef ERL_NIF_DIRTY_SCHEDULER_SUPPORT
{"call_dirty_nif", 3, call_dirty_nif},
{"send_from_dirty_nif", 1, send_from_dirty_nif, ERL_NIF_DIRTY_JOB_CPU_BOUND},
- {"call_dirty_nif_exception", 0, call_dirty_nif_exception, ERL_NIF_DIRTY_JOB_IO_BOUND},
+ {"call_dirty_nif_exception", 1, call_dirty_nif_exception, ERL_NIF_DIRTY_JOB_IO_BOUND},
{"call_dirty_nif_zero_args", 0, call_dirty_nif_zero_args, ERL_NIF_DIRTY_JOB_CPU_BOUND},
#endif
+ {"call_nif_exception", 0, call_nif_exception},
+ {"call_nif_nan_or_inf", 1, call_nif_nan_or_inf},
+ {"call_nif_atom_too_long", 1, call_nif_atom_too_long},
{"is_map_nif", 1, is_map_nif},
{"get_map_size_nif", 1, get_map_size_nif},
{"make_new_map_nif", 0, make_new_map_nif},
diff --git a/erts/emulator/test/op_SUITE.erl b/erts/emulator/test/op_SUITE.erl
index ef4689b850..26f6837f19 100644
--- a/erts/emulator/test/op_SUITE.erl
+++ b/erts/emulator/test/op_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1999-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1999-2015. 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
@@ -273,7 +273,8 @@ run_test_module(Cases, GuardsOk) ->
?line Bbts = lists:foldr(fun internal_bif/2, [Ok], Es),
?line Fun3 = make_function(bif_tests, Bbts),
?line Id = {function,1,id,1,[{clause,1,[{var,1,'I'}],[],[{var,1,'I'}]}]},
- ?line Module = make_module(op_tests, [Fun1,Fun2,Fun3,Id]),
+ Module0 = make_module(op_tests, [Fun1,Fun2,Fun3,Id]),
+ Module = erl_parse:new_anno(Module0),
?line lists:foreach(fun(F) -> io:put_chars([erl_pp:form(F),"\n"]) end, Module),
%% Compile, load, and run the generated module.
@@ -365,13 +366,16 @@ make_module(Name, Funcs) ->
make_function(Name, Body) ->
{function,1,Name,0,[{clause,1,[],[],Body}]}.
-eval(E) ->
+eval(E0) ->
+ E = erl_parse:new_anno(E0),
?line case catch erl_eval:exprs(E, []) of
{'EXIT',Reason} -> {'EXIT',Reason};
{value,Val,_Bs} -> Val
end.
-unvalue(V) -> erl_parse:abstract(V).
+unvalue(V) ->
+ Abstr = erl_parse:abstract(V),
+ erl_parse:anno_to_term(Abstr).
value({nil,_}) -> [];
value({integer,_,X}) -> X;
diff --git a/erts/emulator/test/trace_bif_SUITE.erl b/erts/emulator/test/trace_bif_SUITE.erl
index 063e348836..0f68e7b27c 100644
--- a/erts/emulator/test/trace_bif_SUITE.erl
+++ b/erts/emulator/test/trace_bif_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1998-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1998-2014. 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
@@ -278,13 +278,16 @@ trace_info_old_code(Config) when is_list(Config) ->
?line MFA = {M,F,0} = {test,foo,0},
?line Fname = atom_to_list(M)++".erl",
?line AbsForms =
- [{attribute,1,module,M}, % -module(M).
- {attribute,2,export,[{F,0}]}, % -export([F/0]).
- {function,3,F,0, % F() ->
- [{clause,4,[],[],[{atom,4,F}]}]}], % F.
+ [{attribute,a(1),module,M}, % -module(M).
+ {attribute,a(2),export,[{F,0}]}, % -export([F/0]).
+ {function,a(3),F,0, % F() ->
+ [{clause,a(4),[],[],[{atom,a(4),F}]}]}], % F.
%%
?line {ok,M,Mbin} = compile:forms(AbsForms),
?line {module,M} = code:load_binary(M, Fname, Mbin),
?line true = erlang:delete_module(M),
?line {traced,undefined} = erlang:trace_info(MFA, traced),
ok.
+
+a(L) ->
+ erl_anno:new(L).
diff --git a/erts/etc/common/ct_run.c b/erts/etc/common/ct_run.c
index bb59b93998..9e67b94f30 100644
--- a/erts/etc/common/ct_run.c
+++ b/erts/etc/common/ct_run.c
@@ -239,7 +239,7 @@ int main(int argc, char** argv)
*/
if (ct_mode == VTS_MODE) {
- PUSH4("-s", "webtool", "script_start", "vts");
+ PUSH4("-s", "ct_webtool", "script_start", "vts");
if (browser[0] != '\0') PUSH(browser);
PUSH3("-s", "ct_run", "script_start");
}
diff --git a/erts/etc/common/heart.c b/erts/etc/common/heart.c
index a4f34e21d0..0d1dcacf2c 100644
--- a/erts/etc/common/heart.c
+++ b/erts/etc/common/heart.c
@@ -117,11 +117,12 @@
#define HEART_COMMAND_ENV "HEART_COMMAND"
#define ERL_CRASH_DUMP_SECONDS_ENV "ERL_CRASH_DUMP_SECONDS"
+#define HEART_KILL_SIGNAL "HEART_KILL_SIGNAL"
-#define MSG_HDR_SIZE 2
-#define MSG_HDR_PLUS_OP_SIZE 3
-#define MSG_BODY_SIZE 2048
-#define MSG_TOTAL_SIZE 2050
+#define MSG_HDR_SIZE (2)
+#define MSG_HDR_PLUS_OP_SIZE (3)
+#define MSG_BODY_SIZE (2048)
+#define MSG_TOTAL_SIZE (2050)
unsigned char cmd[MSG_BODY_SIZE];
@@ -555,14 +556,22 @@ kill_old_erlang(void){
static void
kill_old_erlang(void){
pid_t pid;
- int i;
- int res;
+ int i, res;
+ int sig = SIGKILL;
+ char *sigenv = NULL;
+
+ sigenv = get_env(HEART_KILL_SIGNAL);
+ if (sigenv && strcmp(sigenv, "SIGABRT") == 0) {
+ print_error("kill signal SIGABRT requested");
+ sig = SIGABRT;
+ }
+
if(heart_beat_kill_pid != 0){
pid = (pid_t) heart_beat_kill_pid;
- res = kill(pid,SIGKILL);
+ res = kill(pid,sig);
for(i=0; i < 5 && res == 0; ++i){
sleep(1);
- res = kill(pid,SIGKILL);
+ res = kill(pid,sig);
}
if(errno != ESRCH){
print_error("Unable to kill old process, "
diff --git a/erts/etc/common/run_erl_common.c b/erts/etc/common/run_erl_common.c
index 20b78eb05e..ab420e3bee 100644
--- a/erts/etc/common/run_erl_common.c
+++ b/erts/etc/common/run_erl_common.c
@@ -32,6 +32,10 @@
#include <time.h>
#include <unistd.h>
+#ifdef __ANDROID__
+# include <termios.h>
+#endif
+
#ifdef HAVE_SYSLOG_H
# include <syslog.h>
#endif
diff --git a/erts/etc/unix/etp-commands.in b/erts/etc/unix/etp-commands.in
index c117a62a21..3ee092418e 100644
--- a/erts/etc/unix/etp-commands.in
+++ b/erts/etc/unix/etp-commands.in
@@ -146,14 +146,10 @@ define etp-1
etp-immediate-1 ($arg0)
else
# (($arg0) & 0x3) == 0
- if (($arg0) == 0x0)
+ if (($arg0) == etp_the_non_value)
printf "<the non-value>"
else
- if (($arg0) == 0x4)
- printf "<the non-value debug>"
- else
- etp-cp-1 ($arg0)
- end
+ etp-cp-1 ($arg0)
end
end
end
@@ -355,7 +351,32 @@ define etp-boxed-1
etp-array-1 ((Eterm*)(($arg0)&~0x3)) ($arg1) ($arg1) \
1 ((((Eterm*)(($arg0)&~0x3))[0]>>6)+1) '}'
else
- etp-boxed-immediate-1 ($arg0)
+ if (((Eterm*)(($arg0) & ~0x3))[0] & 0x3c) == 0x3c
+ # A map
+ if (((Eterm*)(($arg0) & ~0x3))[0] & 0xc0) == 0x0
+ # Flat map
+ printf "#{Keys:"
+ etp-1 ((flatmap_t*)(($arg0)&~0x3))->keys (($arg1)+1)
+ printf " Values:{"
+ etp-array-1 ((Eterm*)(($arg0)&~0x3)+3) ($arg1) ($arg1) \
+ 0 ((flatmap_t*)(($arg0)&~0x3))->size '}'
+ printf "}"
+ else
+ # Hashmap
+ printf "#<%x>{", (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff)
+ if (((Eterm*)(($arg0) & ~0x3))[0] & 0xc0) >= 0x80
+ # head bitmap/array
+ etp-bitmap-array-1 ((Eterm*)(($arg0)&~0x3)+2) ($arg1) ($arg1) \
+ 0 (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff) '}'
+ else
+ # node bitmap
+ etp-bitmap-array-1 ((Eterm*)(($arg0)&~0x3)+1) ($arg1) ($arg1) \
+ 0 (((((Eterm*)(($arg0)&~0x3))[0])>>(6+2+8))&0xffff) '}'
+ end
+ end
+ else
+ etp-boxed-immediate-1 ($arg0)
+ end
end
end
end
@@ -478,6 +499,36 @@ define etp-array-1
end
end
+define etp-bitmap-array-1
+# Args: Eterm* p, int depth, int width, int pos, int bitmap, int end_char
+#
+# Reentrant
+#
+# Same as etp-array-1 with size = bitcount(bitmap)
+#
+ if ($arg4) & 1 != 0
+ if (($arg1) < $etp_max_depth) && (($arg2) < $etp_max_depth)
+ etp-1 (($arg0)[($arg3)]) (($arg1)+1)
+ if (($arg4) & (($arg4)-1)) != 0
+ printf ","
+ end
+ etp-bitmap-array-1 ($arg0) ($arg1) (($arg2)+1) (($arg3)+1) (($arg4)>>1) ($arg5)
+ else
+ printf "...%c", ($arg5)
+ end
+ else
+ if ($arg4) == 0
+ printf "%c", ($arg5)
+ else
+ etp-bitmap-array-1 $arg0 $arg1 $arg2 $arg3 (($arg4)>>1) $arg5
+
+ # WARNING: One might be tempted to optimize the bitcounting here
+ # by passing the bitmap argument as ($arg4 & ($arg4 - 1)). This is a very
+ # bad idea as arguments are passed as string substitution.
+ # The size of $arg4 would thus grow exponentially for each recursion.
+ end
+ end
+end
#define etpa-1