diff --git a/.hgtags-top-repo b/.hgtags-top-repo index ca1497b3968..d83fa5ca611 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -228,3 +228,4 @@ b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104 5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105 8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 +0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 diff --git a/Makefile b/Makefile index f7b9d1b35e3..2ef4bb99853 100644 --- a/Makefile +++ b/Makefile @@ -404,7 +404,6 @@ COMPILER_PATH.desc = Compiler install directory CACERTS_FILE.desc = Location of certificates file DEVTOOLS_PATH.desc = Directory containing zip and gnumake CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files -DXSDK_PATH.desc = Root directory of DirectX SDK # Make variables to print out (description and value) VARIABLE_PRINTVAL_LIST += \ @@ -429,17 +428,6 @@ VARIABLE_CHECKDIR_LIST += \ VARIABLE_CHECKFIL_LIST += \ CACERTS_FILE -# Some are windows specific -ifeq ($(PLATFORM), windows) - -VARIABLE_PRINTVAL_LIST += \ - DXSDK_PATH - -VARIABLE_CHECKDIR_LIST += \ - DXSDK_PATH - -endif - # For pattern rules below, so all are treated the same DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval) DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir) diff --git a/README-builds.html b/README-builds.html index 71c05c0fbf4..14796a27e87 100644 --- a/README-builds.html +++ b/README-builds.html @@ -444,10 +444,6 @@ Install Visual Studio 2010 -
  • - Install the - Microsoft DirectX SDK -
  • @@ -971,25 +967,6 @@ developer install location - - --with-dxsdk=path - - select location of the Windows Direct X SDK install -
    - The Microsoft DirectX 9.0 SDK - header files and libraries - from the Summer 2004 edition - are required for building OpenJDK. - This SDK can be downloaded from - - Microsoft DirectX 9.0 SDK (Summer 2004). - If the link above becomes obsolete, the SDK can be found from - the Microsoft Download Site - (search with "DirectX 9.0 SDK Update Summer 2004"). - Installation usually will set the environment variable - DXSDK_DIR to it's install location. - - --with-freetype=path diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4 index 126993b5cd7..f3911ff9bd9 100644 --- a/common/autoconf/basics.m4 +++ b/common/autoconf/basics.m4 @@ -203,6 +203,15 @@ AC_DEFUN([BASIC_REMOVE_SYMBOLIC_LINKS], fi ]) +# Register a --with argument but mark it as deprecated +# $1: The name of the with argument to deprecate, not including --with- +AC_DEFUN([BASIC_DEPRECATED_ARG_WITH], +[ + AC_ARG_WITH($1, [AS_HELP_STRING([--with-$1], + [Deprecated. Option is kept for backwards compatibility and is ignored])], + [AC_MSG_WARN([Option --with-$1 is deprecated and will be ignored.])]) +]) + AC_DEFUN_ONCE([BASIC_INIT], [ # Save the original command line. This is passed to us by the wrapper configure script. diff --git a/common/autoconf/basics_windows.m4 b/common/autoconf/basics_windows.m4 index 9ddb9e8c5c0..0a26d830239 100644 --- a/common/autoconf/basics_windows.m4 +++ b/common/autoconf/basics_windows.m4 @@ -211,7 +211,7 @@ AC_DEFUN([BASIC_FIXUP_EXECUTABLE_CYGWIN], # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then diff --git a/common/autoconf/build-aux/autoconf-config.guess b/common/autoconf/build-aux/autoconf-config.guess index 3aa7f690629..15ee4389269 100644 --- a/common/autoconf/build-aux/autoconf-config.guess +++ b/common/autoconf/build-aux/autoconf-config.guess @@ -26,10 +26,10 @@ # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 -# Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, +# 2011, 2012 Free Software Foundation, Inc. -timestamp='2008-01-23' +timestamp='2012-02-10' # 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 @@ -42,9 +42,7 @@ timestamp='2008-01-23' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -52,16 +50,16 @@ timestamp='2008-01-23' # the same distribution terms that you use for the rest of that program. -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. +# Originally written by Per Bothner. Please send patches (context +# diff format) to and include a ChangeLog +# entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. +# 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 me=`echo "$0" | sed -e 's,.*/,,'` @@ -81,8 +79,9 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, +2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 +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." @@ -169,7 +168,7 @@ UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward @@ -195,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null + | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? @@ -205,7 +204,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in fi ;; *) - os=netbsd + os=netbsd ;; esac # The OS release @@ -248,7 +247,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on @@ -294,7 +293,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead @@ -320,7 +322,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo s390-ibm-zvmoe exit ;; *:OS400:*:*) - echo powerpc-ibm-os400 + echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} @@ -349,14 +351,33 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; + s390x:SunOS:*:*) + echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux${UNAME_RELEASE} + exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + eval $set_cc_for_build + SUN_ARCH="i386" + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH="x86_64" + fi + fi + echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize @@ -400,23 +421,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} - exit ;; + exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; + echo m68k-milan-mint${UNAME_RELEASE} + exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; + echo m68k-hades-mint${UNAME_RELEASE} + exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; + echo m68k-unknown-mint${UNAME_RELEASE} + exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; @@ -486,8 +507,8 @@ EOF echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ @@ -500,7 +521,7 @@ EOF else echo i586-dg-dgux${UNAME_RELEASE} fi - exit ;; + exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; @@ -557,7 +578,7 @@ EOF echo rs6000-ibm-aix3.2 fi exit ;; - *:AIX:*:[456]) + *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -600,52 +621,52 @@ EOF 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac + esac ;; + esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + sed 's/^ //' << EOF >$dummy.c - #define _HPUX_SOURCE - #include - #include + #define _HPUX_SOURCE + #include + #include - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa @@ -665,7 +686,7 @@ EOF # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null + grep -q __LP64__ then HP_ARCH="hppa2.0w" else @@ -736,22 +757,22 @@ EOF exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd - exit ;; + exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi - exit ;; + exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd - exit ;; + exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd - exit ;; + exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd - exit ;; + exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; @@ -775,14 +796,14 @@ EOF exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} @@ -794,13 +815,12 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=`/usr/bin/uname -p` + case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) @@ -809,19 +829,22 @@ EOF *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; + i*:MSYS*:*) + echo ${UNAME_MACHINE}-pc-msys + exit ;; i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + # uname -m includes "-pc" on this system. + echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - *:Interix*:[3456]*) - case ${UNAME_MACHINE} in + *:Interix*:*) + case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; - EM64T | authenticamd) + authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) @@ -831,6 +854,9 @@ EOF [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; + 8664:Windows_NT:*) + echo x86_64-pc-mks + exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we @@ -860,92 +886,13 @@ EOF i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix 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 - else - echo ${UNAME_MACHINE}-unknown-linux-gnueabi - fi - exit ;; - avr32*:Linux:*:*) + aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; @@ -955,11 +902,90 @@ EOF EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null + 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} 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 + 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 + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + cris:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + crisv32:Linux:*:*) + echo ${UNAME_MACHINE}-axis-linux-gnu + exit ;; + frv:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + hexagon:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + 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}" + exit ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m32r*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval $set_cc_for_build + sed 's/^ //' << EOF >$dummy.c + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` + test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } + ;; + or32:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-gnu + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in @@ -968,14 +994,17 @@ EOF *) echo hppa-unknown-linux-gnu ;; esac exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-gnu + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu @@ -983,78 +1012,18 @@ EOF sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + tile*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu + echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both @@ -1062,11 +1031,11 @@ EOF echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. + # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) @@ -1083,7 +1052,7 @@ EOF i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) @@ -1098,7 +1067,7 @@ EOF fi exit ;; i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. + # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; @@ -1126,10 +1095,13 @@ EOF exit ;; pc:*:*:*) # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configury will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; @@ -1164,8 +1136,18 @@ EOF /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; @@ -1178,7 +1160,7 @@ EOF rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) @@ -1198,10 +1180,10 @@ EOF echo ns32k-sni-sysv fi exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm @@ -1227,11 +1209,11 @@ EOF exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv${UNAME_RELEASE} else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv${UNAME_RELEASE} fi - exit ;; + exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; @@ -1241,6 +1223,9 @@ EOF BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1267,12 +1252,17 @@ EOF exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build - echo "int main(){}" > $dummy.c - if test "`$CC_FOR_BUILD -o $dummy $dummy.c; file $dummy | grep -c x86_64`" = 1 ; then - UNAME_PROCESSOR=x86_64 - fi 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 echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} @@ -1288,6 +1278,9 @@ EOF *:QNX:*:4*) echo i386-pc-qnx exit ;; + NEO-?:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk${UNAME_RELEASE} + exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; @@ -1333,13 +1326,13 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` + UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; @@ -1354,6 +1347,12 @@ EOF i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; + i*86:AROS:*:*) + echo ${UNAME_MACHINE}-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo ${UNAME_MACHINE}-unknown-esx + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 @@ -1376,11 +1375,11 @@ main () #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 - "4" + "4" #else - "" + "" #endif - ); exit (0); + ); exit (0); #endif #endif diff --git a/common/autoconf/configure b/common/autoconf/configure index 8e4560df114..7378efe379d 100644 --- a/common/autoconf/configure +++ b/common/autoconf/configure @@ -219,9 +219,4 @@ else echo configure exiting with result code $conf_result_code fi -# Move the log file to the output root, if this was successfully created -if test -d "$OUTPUT_ROOT"; then - mv -f config.log "$OUTPUT_ROOT" 2> /dev/null -fi - exit $conf_result_code diff --git a/common/autoconf/configure.ac b/common/autoconf/configure.ac index 274f278fb3d..ad8bd97cea3 100644 --- a/common/autoconf/configure.ac +++ b/common/autoconf/configure.ac @@ -232,9 +232,15 @@ CUSTOM_LATE_HOOK # We're messing a bit with internal autoconf variables to put the config.status # in the output directory instead of the current directory. CONFIG_STATUS="$OUTPUT_ROOT/config.status" + # Create the actual output files. Now the main work of configure is done. AC_OUTPUT +# Try to move the config.log file to the output directory. +if test -e ./config.log; then + $MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null +fi + # Make the compare script executable $CHMOD +x $OUTPUT_ROOT/compare.sh diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 7679cc5c4df..7a65a92ecc4 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -709,7 +709,6 @@ STATIC_LIBRARY SHARED_LIBRARY OBJ_SUFFIX COMPILER_NAME -TARGET_BITS_FLAG JT_HOME JTREGEXE LIPO @@ -766,8 +765,6 @@ BUILD_LD BUILD_CXX BUILD_CC MSVCR_DLL -DXSDK_INCLUDE_PATH -DXSDK_LIB_PATH VS_PATH VS_LIB VS_INCLUDE @@ -1031,6 +1028,7 @@ with_override_corba with_override_jaxp with_override_jaxws with_override_hotspot +with_override_nashorn with_override_jdk with_import_hotspot with_msvcr_dll @@ -1784,17 +1782,19 @@ Optional Packages: --with-override-jaxp use this jaxp dir for the build --with-override-jaxws use this jaxws dir for the build --with-override-hotspot use this hotspot dir for the build + --with-override-nashorn use this nashorn dir for the build --with-override-jdk use this jdk dir for the build --with-import-hotspot import hotspot binaries from this jdk image or hotspot build dist dir instead of building from source --with-msvcr-dll copy this msvcr100.dll into the built JDK (Windows only) [probed] - --with-dxsdk the DirectX SDK (Windows only) [probed] - --with-dxsdk-lib the DirectX SDK lib directory (Windows only) - [probed] - --with-dxsdk-include the DirectX SDK include directory (Windows only) - [probed] + --with-dxsdk Deprecated. Option is kept for backwards + compatibility and is ignored + --with-dxsdk-lib Deprecated. Option is kept for backwards + compatibility and is ignored + --with-dxsdk-include Deprecated. Option is kept for backwards + compatibility and is ignored --with-jtreg Regression Test Harness [probed] --with-extra-cflags extra flags to be used when compiling jdk c-files --with-extra-cxxflags extra flags to be used when compiling jdk c++-files @@ -3144,6 +3144,10 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. +# Register a --with argument but mark it as deprecated +# $1: The name of the with argument to deprecate, not including --with- + + # Test that variable $1 denoting a program is not empty. If empty, exit with an error. @@ -3805,10 +3809,6 @@ fi -# Setup the DXSDK paths - - - @@ -3818,7 +3818,7 @@ fi #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1378914658 +DATE_WHEN_GENERATED=1379504921 ############################################################################### # @@ -8352,7 +8352,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -8709,7 +8709,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -9063,7 +9063,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -9422,7 +9422,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -9775,7 +9775,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -11075,7 +11075,7 @@ elif test "x$with_user_release_suffix" != x; then else BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` fi @@ -16102,6 +16102,10 @@ if test "x$with_add_source_root" != x; then test -f $with_add_source_root/hotspot/make/Makefile; then as_fn_error $? "Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources." "$LINENO" 5 fi + if test -f $with_add_source_root/nashorn/makefiles/Makefile || \ + test -f $with_add_source_root/nashorn/make/Makefile; then + as_fn_error $? "Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources." "$LINENO" 5 + fi if test -f $with_add_source_root/jdk/makefiles/Makefile || \ test -f $with_add_source_root/jdk/make/Makefile; then as_fn_error $? "Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources." "$LINENO" 5 @@ -16137,6 +16141,10 @@ if test "x$with_override_source_root" != x; then test -f $with_override_source_root/hotspot/make/Makefile; then as_fn_error $? "Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override." "$LINENO" 5 fi + if test -f $with_override_source_root/nashorn/makefiles/Makefile || \ + test -f $with_override_source_root/nashorn/make/Makefile; then + as_fn_error $? "Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override." "$LINENO" 5 + fi if test -f $with_override_source_root/jdk/makefiles/Makefile || \ test -f $with_override_source_root/jdk/make/Makefile; then as_fn_error $? "Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override." "$LINENO" 5 @@ -16199,6 +16207,13 @@ fi +# Check whether --with-override-nashorn was given. +if test "${with_override_nashorn+set}" = set; then : + withval=$with_override_nashorn; +fi + + + # Check whether --with-override-jdk was given. if test "${with_override_jdk+set}" = set; then : withval=$with_override_jdk; @@ -16276,7 +16291,7 @@ if test "x$with_override_nashorn" != x; then cd "$with_override_nashorn" NASHORN_TOPDIR="`pwd`" cd "$CURDIR" - if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then + if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then as_fn_error $? "You have to override nashorn with a full nashorn repo!" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if nashorn should be overridden" >&5 @@ -17086,7 +17101,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -17586,437 +17601,29 @@ $as_echo "$as_me: The path of MSVCR_DLL, which resolves as \"$path\", is invalid # Check whether --with-dxsdk was given. if test "${with_dxsdk+set}" = set; then : - withval=$with_dxsdk; + withval=$with_dxsdk; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-dxsdk is deprecated and will be ignored." >&2;} fi + + # Check whether --with-dxsdk-lib was given. if test "${with_dxsdk_lib+set}" = set; then : - withval=$with_dxsdk_lib; + withval=$with_dxsdk_lib; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-dxsdk-lib is deprecated and will be ignored." >&2;} fi + + # Check whether --with-dxsdk-include was given. if test "${with_dxsdk_include+set}" = set; then : - withval=$with_dxsdk_include; + withval=$with_dxsdk_include; { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&5 +$as_echo "$as_me: WARNING: Option --with-dxsdk-include is deprecated and will be ignored." >&2;} fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK" >&5 -$as_echo_n "checking for DirectX SDK... " >&6; } - - if test "x$with_dxsdk" != x; then - dxsdk_path="$with_dxsdk" - elif test "x$DXSDK_DIR" != x; then - dxsdk_path="$DXSDK_DIR" - elif test -d "C:/DXSDK"; then - dxsdk_path="C:/DXSDK" - else - as_fn_error $? "Could not find the DirectX SDK" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dxsdk_path" >&5 -$as_echo "$dxsdk_path" >&6; } - - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$dxsdk_path" - new_path=`$CYGPATH -u "$path"` - - # Cygwin tries to hide some aspects of the Windows file system, such that binaries are - # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered - # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then - # "foo.exe" is OK but "foo" is an error. - # - # This test is therefore slightly more accurate than "test -f" to check for file precense. - # It is also a way to make sure we got the proper file name for the real test later on. - test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` - if test "x$test_shortpath" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of dxsdk_path" "$LINENO" 5 - fi - - # Call helper function which possibly converts this using DOS-style short mode. - # If so, the updated path is stored in $new_path. - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - shortmode_path=`$CYGPATH -s -m -a "$input_path"` - path_after_shortmode=`$CYGPATH -u "$shortmode_path"` - if test "x$path_after_shortmode" != "x$input_to_shortpath"; then - # Going to short mode and back again did indeed matter. Since short mode is - # case insensitive, let's make it lowercase to improve readability. - shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Now convert it back to Unix-stile (cygpath) - input_path=`$CYGPATH -u "$shortmode_path"` - new_path="$input_path" - fi - fi - - test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` - if test "x$test_cygdrive_prefix" = x; then - # As a simple fix, exclude /usr/bin since it's not a real path. - if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then - # The path is in a Cygwin special directory (e.g. /home). We need this converted to - # a path prefixed by /cygdrive for fixpath to work. - new_path="$CYGWIN_ROOT_PATH$input_path" - fi - fi - - - if test "x$path" != "x$new_path"; then - dxsdk_path="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$dxsdk_path" - has_colon=`$ECHO $path | $GREP ^.:` - new_path="$path" - if test "x$has_colon" = x; then - # Not in mixed or Windows style, start by that. - new_path=`cmd //c echo $path` - fi - - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - fi - - - windows_path="$new_path" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - new_path="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - new_path="$unix_path" - fi - - if test "x$path" != "x$new_path"; then - dxsdk_path="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting dxsdk_path to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting dxsdk_path to \"$new_path\"" >&6;} - fi - - # Save the first 10 bytes of this path to the storage, so fixpath can work. - all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") - - else - # We're on a posix platform. Hooray! :) - path="$dxsdk_path" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of dxsdk_path, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 - fi - - # Use eval to expand a potential ~ - eval path="$path" - if test ! -f "$path" && test ! -d "$path"; then - as_fn_error $? "The path of dxsdk_path, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - dxsdk_path="`cd "$path"; $THEPWDCMD -L`" - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK lib dir" >&5 -$as_echo_n "checking for DirectX SDK lib dir... " >&6; } - if test "x$with_dxsdk_lib" != x; then - DXSDK_LIB_PATH="$with_dxsdk_lib" - elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then - DXSDK_LIB_PATH="$dxsdk_path/Lib/x64" - else - DXSDK_LIB_PATH="$dxsdk_path/Lib" - fi - # dsound.lib is linked to in jsoundds - if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then - as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_LIB_PATH" >&5 -$as_echo "$DXSDK_LIB_PATH" >&6; } - - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$DXSDK_LIB_PATH" - new_path=`$CYGPATH -u "$path"` - - # Cygwin tries to hide some aspects of the Windows file system, such that binaries are - # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered - # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then - # "foo.exe" is OK but "foo" is an error. - # - # This test is therefore slightly more accurate than "test -f" to check for file precense. - # It is also a way to make sure we got the proper file name for the real test later on. - test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` - if test "x$test_shortpath" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of DXSDK_LIB_PATH" "$LINENO" 5 - fi - - # Call helper function which possibly converts this using DOS-style short mode. - # If so, the updated path is stored in $new_path. - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - shortmode_path=`$CYGPATH -s -m -a "$input_path"` - path_after_shortmode=`$CYGPATH -u "$shortmode_path"` - if test "x$path_after_shortmode" != "x$input_to_shortpath"; then - # Going to short mode and back again did indeed matter. Since short mode is - # case insensitive, let's make it lowercase to improve readability. - shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Now convert it back to Unix-stile (cygpath) - input_path=`$CYGPATH -u "$shortmode_path"` - new_path="$input_path" - fi - fi - - test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` - if test "x$test_cygdrive_prefix" = x; then - # As a simple fix, exclude /usr/bin since it's not a real path. - if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then - # The path is in a Cygwin special directory (e.g. /home). We need this converted to - # a path prefixed by /cygdrive for fixpath to work. - new_path="$CYGWIN_ROOT_PATH$input_path" - fi - fi - - - if test "x$path" != "x$new_path"; then - DXSDK_LIB_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$DXSDK_LIB_PATH" - has_colon=`$ECHO $path | $GREP ^.:` - new_path="$path" - if test "x$has_colon" = x; then - # Not in mixed or Windows style, start by that. - new_path=`cmd //c echo $path` - fi - - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - fi - - - windows_path="$new_path" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - new_path="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - new_path="$unix_path" - fi - - if test "x$path" != "x$new_path"; then - DXSDK_LIB_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_LIB_PATH to \"$new_path\"" >&6;} - fi - - # Save the first 10 bytes of this path to the storage, so fixpath can work. - all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") - - else - # We're on a posix platform. Hooray! :) - path="$DXSDK_LIB_PATH" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_LIB_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 - fi - - # Use eval to expand a potential ~ - eval path="$path" - if test ! -f "$path" && test ! -d "$path"; then - as_fn_error $? "The path of DXSDK_LIB_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - DXSDK_LIB_PATH="`cd "$path"; $THEPWDCMD -L`" - fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DirectX SDK include dir" >&5 -$as_echo_n "checking for DirectX SDK include dir... " >&6; } - if test "x$with_dxsdk_include" != x; then - DXSDK_INCLUDE_PATH="$with_dxsdk_include" - else - DXSDK_INCLUDE_PATH="$dxsdk_path/Include" - fi - # dsound.h is included in jsoundds - if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then - as_fn_error $? "Invalid DirectX SDK lib dir" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DXSDK_INCLUDE_PATH" >&5 -$as_echo "$DXSDK_INCLUDE_PATH" >&6; } - - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - - # Input might be given as Windows format, start by converting to - # unix format. - path="$DXSDK_INCLUDE_PATH" - new_path=`$CYGPATH -u "$path"` - - # Cygwin tries to hide some aspects of the Windows file system, such that binaries are - # named .exe but called without that suffix. Therefore, "foo" and "foo.exe" are considered - # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then - # "foo.exe" is OK but "foo" is an error. - # - # This test is therefore slightly more accurate than "test -f" to check for file precense. - # It is also a way to make sure we got the proper file name for the real test later on. - test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` - if test "x$test_shortpath" = x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Cannot locate the the path of DXSDK_INCLUDE_PATH" "$LINENO" 5 - fi - - # Call helper function which possibly converts this using DOS-style short mode. - # If so, the updated path is stored in $new_path. - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-._/a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - shortmode_path=`$CYGPATH -s -m -a "$input_path"` - path_after_shortmode=`$CYGPATH -u "$shortmode_path"` - if test "x$path_after_shortmode" != "x$input_to_shortpath"; then - # Going to short mode and back again did indeed matter. Since short mode is - # case insensitive, let's make it lowercase to improve readability. - shortmode_path=`$ECHO "$shortmode_path" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - # Now convert it back to Unix-stile (cygpath) - input_path=`$CYGPATH -u "$shortmode_path"` - new_path="$input_path" - fi - fi - - test_cygdrive_prefix=`$ECHO $input_path | $GREP ^/cygdrive/` - if test "x$test_cygdrive_prefix" = x; then - # As a simple fix, exclude /usr/bin since it's not a real path. - if test "x`$ECHO $new_path | $GREP ^/usr/bin/`" = x; then - # The path is in a Cygwin special directory (e.g. /home). We need this converted to - # a path prefixed by /cygdrive for fixpath to work. - new_path="$CYGWIN_ROOT_PATH$input_path" - fi - fi - - - if test "x$path" != "x$new_path"; then - DXSDK_INCLUDE_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;} - fi - - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - - path="$DXSDK_INCLUDE_PATH" - has_colon=`$ECHO $path | $GREP ^.:` - new_path="$path" - if test "x$has_colon" = x; then - # Not in mixed or Windows style, start by that. - new_path=`cmd //c echo $path` - fi - - - input_path="$new_path" - # Check if we need to convert this using DOS-style short mode. If the path - # contains just simple characters, use it. Otherwise (spaces, weird characters), - # take no chances and rewrite it. - # Note: m4 eats our [], so we need to use [ and ] instead. - has_forbidden_chars=`$ECHO "$input_path" | $GREP [^-_/:a-zA-Z0-9]` - if test "x$has_forbidden_chars" != x; then - # Now convert it to mixed DOS-style, short mode (no spaces, and / instead of \) - new_path=`cmd /c "for %A in (\"$input_path\") do @echo %~sA"|$TR \\\\\\\\ / | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - fi - - - windows_path="$new_path" - if test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.cygwin"; then - unix_path=`$CYGPATH -u "$windows_path"` - new_path="$unix_path" - elif test "x$OPENJDK_BUILD_OS_ENV" = "xwindows.msys"; then - unix_path=`$ECHO "$windows_path" | $SED -e 's,^\\(.\\):,/\\1,g' -e 's,\\\\,/,g'` - new_path="$unix_path" - fi - - if test "x$path" != "x$new_path"; then - DXSDK_INCLUDE_PATH="$new_path" - { $as_echo "$as_me:${as_lineno-$LINENO}: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&5 -$as_echo "$as_me: Rewriting DXSDK_INCLUDE_PATH to \"$new_path\"" >&6;} - fi - - # Save the first 10 bytes of this path to the storage, so fixpath can work. - all_fixpath_prefixes=("${all_fixpath_prefixes[@]}" "${new_path:0:10}") - - else - # We're on a posix platform. Hooray! :) - path="$DXSDK_INCLUDE_PATH" - has_space=`$ECHO "$path" | $GREP " "` - if test "x$has_space" != x; then - { $as_echo "$as_me:${as_lineno-$LINENO}: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&5 -$as_echo "$as_me: The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is invalid." >&6;} - as_fn_error $? "Spaces are not allowed in this path." "$LINENO" 5 - fi - - # Use eval to expand a potential ~ - eval path="$path" - if test ! -f "$path" && test ! -d "$path"; then - as_fn_error $? "The path of DXSDK_INCLUDE_PATH, which resolves as \"$path\", is not found." "$LINENO" 5 - fi - - DXSDK_INCLUDE_PATH="`cd "$path"; $THEPWDCMD -L`" - fi - - - - - LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH" - fi @@ -18140,7 +17747,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -18451,7 +18058,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -18757,7 +18364,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -19350,7 +18957,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -19786,7 +19393,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -20922,7 +20529,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -21358,7 +20965,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -22259,7 +21866,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -22640,7 +22247,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -22987,7 +22594,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -23324,7 +22931,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -23645,7 +23252,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -24020,7 +23627,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -24326,7 +23933,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -24737,7 +24344,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -25137,7 +24744,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -25466,7 +25073,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -25778,7 +25385,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -26084,7 +25691,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -26390,7 +25997,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -26696,7 +26303,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -27055,7 +26662,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -27415,7 +27022,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -27788,7 +27395,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -28159,7 +27766,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -28468,7 +28075,7 @@ $as_echo "$as_me: You might be mixing spaces in the path and extra arguments, wh # the same file, most of the time (as in "test -f"). But not when running cygpath -s, then # "foo.exe" is OK but "foo" is an error. # - # This test is therefore slightly more accurate than "test -f" to check for file precense. + # This test is therefore slightly more accurate than "test -f" to check for file presence. # It is also a way to make sure we got the proper file name for the real test later on. test_shortpath=`$CYGPATH -s -m "$new_path" 2> /dev/null` if test "x$test_shortpath" = x; then @@ -28830,35 +28437,41 @@ done if test "x$OPENJDK_TARGET_OS" = xsolaris; then # Always specify -m flags on Solaris - # keep track of c/cxx flags that we added outselves... - # to prevent emitting warning... - TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" + # When we add flags to the "official" CFLAGS etc, we need to + # keep track of these additions in ADDED_CFLAGS etc. These + # will later be checked to make sure only controlled additions + # have been made to CFLAGS etc. + ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + CFLAGS="${CFLAGS}${ADDED_CFLAGS}" + CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" + LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" - CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" - LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" - - CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" - CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" - LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" + CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" + CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" + LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" elif test "x$COMPILE_TYPE" = xreduced; then if test "x$OPENJDK_TARGET_OS" != xwindows; then # Specify -m if running reduced on other Posix platforms - # keep track of c/cxx flags that we added outselves... - # to prevent emitting warning... - TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" + # When we add flags to the "official" CFLAGS etc, we need to + # keep track of these additions in ADDED_CFLAGS etc. These + # will later be checked to make sure only controlled additions + # have been made to CFLAGS etc. + ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + CFLAGS="${CFLAGS}${ADDED_CFLAGS}" + CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" + LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" - CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" - LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" - - CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" - CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" - LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" + CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" + CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" + LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" fi fi @@ -33618,6 +33231,7 @@ fi # We're messing a bit with internal autoconf variables to put the config.status # in the output directory instead of the current directory. CONFIG_STATUS="$OUTPUT_ROOT/config.status" + # Create the actual output files. Now the main work of configure is done. cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -34899,6 +34513,11 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi +# Try to move the config.log file to the output directory. +if test -e ./config.log; then + $MV -f ./config.log "$OUTPUT_ROOT/config.log" 2> /dev/null +fi + # Make the compare script executable $CHMOD +x $OUTPUT_ROOT/compare.sh diff --git a/common/autoconf/jdk-options.m4 b/common/autoconf/jdk-options.m4 index ba14373e593..b1c99bbe7dc 100644 --- a/common/autoconf/jdk-options.m4 +++ b/common/autoconf/jdk-options.m4 @@ -446,7 +446,7 @@ elif test "x$with_user_release_suffix" != x; then else BUILD_DATE=`date '+%Y_%m_%d_%H_%M'` # Avoid [:alnum:] since it depends on the locale. - CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyz0123456789'` + CLEAN_USERNAME=`echo "$USER" | $TR -d -c 'abcdefghijklmnopqrstuvqxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'` USER_RELEASE_SUFFIX=`echo "${CLEAN_USERNAME}_${BUILD_DATE}" | $TR 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` fi AC_SUBST(USER_RELEASE_SUFFIX) diff --git a/common/autoconf/platform.m4 b/common/autoconf/platform.m4 index 71ae2ceab7b..96c710d8a18 100644 --- a/common/autoconf/platform.m4 +++ b/common/autoconf/platform.m4 @@ -422,18 +422,21 @@ AC_SUBST(OS_VERSION_MICRO) # Add -mX to various FLAGS variables. AC_DEFUN([PLATFORM_SET_COMPILER_TARGET_BITS_FLAGS], [ - # keep track of c/cxx flags that we added outselves... - # to prevent emitting warning... - TARGET_BITS_FLAG="-m${OPENJDK_TARGET_CPU_BITS}" - AC_SUBST(TARGET_BITS_FLAG) + # When we add flags to the "official" CFLAGS etc, we need to + # keep track of these additions in ADDED_CFLAGS etc. These + # will later be checked to make sure only controlled additions + # have been made to CFLAGS etc. + ADDED_CFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_CXXFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" + ADDED_LDFLAGS=" -m${OPENJDK_TARGET_CPU_BITS}" - CFLAGS="${CFLAGS} ${TARGET_BITS_FLAG}" - CXXFLAGS="${CXXFLAGS} ${TARGET_BITS_FLAG}" - LDFLAGS="${LDFLAGS} ${TARGET_BITS_FLAG}" + CFLAGS="${CFLAGS}${ADDED_CFLAGS}" + CXXFLAGS="${CXXFLAGS}${ADDED_CXXFLAGS}" + LDFLAGS="${LDFLAGS}${ADDED_LDFLAGS}" - CFLAGS_JDK="${CFLAGS_JDK} ${TARGET_BITS_FLAG}" - CXXFLAGS_JDK="${CXXFLAGS_JDK} ${TARGET_BITS_FLAG}" - LDFLAGS_JDK="${LDFLAGS_JDK} ${TARGET_BITS_FLAG}" + CFLAGS_JDK="${CFLAGS_JDK}${ADDED_CFLAGS}" + CXXFLAGS_JDK="${CXXFLAGS_JDK}${ADDED_CXXFLAGS}" + LDFLAGS_JDK="${LDFLAGS_JDK}${ADDED_LDFLAGS}" ]) AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_TARGET_BITS], diff --git a/common/autoconf/source-dirs.m4 b/common/autoconf/source-dirs.m4 index bb0aba1b826..e040cc82f69 100644 --- a/common/autoconf/source-dirs.m4 +++ b/common/autoconf/source-dirs.m4 @@ -101,6 +101,10 @@ if test "x$with_add_source_root" != x; then test -f $with_add_source_root/hotspot/make/Makefile; then AC_MSG_ERROR([Your add source root seems to contain a full hotspot repo! An add source root should only contain additional sources.]) fi + if test -f $with_add_source_root/nashorn/makefiles/Makefile || \ + test -f $with_add_source_root/nashorn/make/Makefile; then + AC_MSG_ERROR([Your add source root seems to contain a full nashorn repo! An add source root should only contain additional sources.]) + fi if test -f $with_add_source_root/jdk/makefiles/Makefile || \ test -f $with_add_source_root/jdk/make/Makefile; then AC_MSG_ERROR([Your add source root seems to contain a full JDK repo! An add source root should only contain additional sources.]) @@ -136,6 +140,10 @@ if test "x$with_override_source_root" != x; then test -f $with_override_source_root/hotspot/make/Makefile; then AC_MSG_ERROR([Your override source root seems to contain a full hotspot repo! An override source root should only contain sources that override.]) fi + if test -f $with_override_source_root/nashorn/makefiles/Makefile || \ + test -f $with_override_source_root/nashorn/make/Makefile; then + AC_MSG_ERROR([Your override source root seems to contain a full nashorn repo! An override source root should only contain sources that override.]) + fi if test -f $with_override_source_root/jdk/makefiles/Makefile || \ test -f $with_override_source_root/jdk/make/Makefile; then AC_MSG_ERROR([Your override source root seems to contain a full JDK repo! An override source root should only contain sources that override.]) @@ -177,6 +185,9 @@ AC_ARG_WITH(override-jaxws, [AS_HELP_STRING([--with-override-jaxws], AC_ARG_WITH(override-hotspot, [AS_HELP_STRING([--with-override-hotspot], [use this hotspot dir for the build])]) +AC_ARG_WITH(override-nashorn, [AS_HELP_STRING([--with-override-nashorn], + [use this nashorn dir for the build])]) + AC_ARG_WITH(override-jdk, [AS_HELP_STRING([--with-override-jdk], [use this jdk dir for the build])]) @@ -241,7 +252,7 @@ if test "x$with_override_nashorn" != x; then cd "$with_override_nashorn" NASHORN_TOPDIR="`pwd`" cd "$CURDIR" - if ! test -f $NASHORN_TOPDIR/makefiles/BuildNashorn.gmk; then + if ! test -f $NASHORN_TOPDIR/makefiles/Makefile; then AC_MSG_ERROR([You have to override nashorn with a full nashorn repo!]) fi AC_MSG_CHECKING([if nashorn should be overridden]) diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in index d2ffb614bcc..7e186693700 100644 --- a/common/autoconf/spec.gmk.in +++ b/common/autoconf/spec.gmk.in @@ -291,10 +291,6 @@ X_CFLAGS:=@X_CFLAGS@ X_LIBS:=@X_LIBS@ OPENWIN_HOME:=@OPENWIN_HOME@ -# DirectX SDK -DXSDK_LIB_PATH=@DXSDK_LIB_PATH@ -DXSDK_INCLUDE_PATH=@DXSDK_INCLUDE_PATH@ - # The lowest required version of macosx to enforce compatiblity for MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@ @@ -304,7 +300,6 @@ MACOSX_VERSION_MIN=@MACOSX_VERSION_MIN@ COMPILER_TYPE:=@COMPILER_TYPE@ COMPILER_NAME:=@COMPILER_NAME@ -TARGET_BITS_FLAG=@TARGET_BITS_FLAG@ COMPILER_SUPPORTS_TARGET_BITS_FLAG=@COMPILER_SUPPORTS_TARGET_BITS_FLAG@ CC_OUT_OPTION:=@CC_OUT_OPTION@ diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4 index efaecc18960..21733003023 100644 --- a/common/autoconf/toolchain.m4 +++ b/common/autoconf/toolchain.m4 @@ -176,7 +176,9 @@ AC_DEFUN([TOOLCHAIN_SETUP_PATHS], [ if test "x$OPENJDK_TARGET_OS" = "xwindows"; then TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV - TOOLCHAIN_SETUP_DXSDK + BASIC_DEPRECATED_ARG_WITH([dxsdk]) + BASIC_DEPRECATED_ARG_WITH([dxsdk-lib]) + BASIC_DEPRECATED_ARG_WITH([dxsdk-include]) fi AC_SUBST(MSVCR_DLL) diff --git a/common/autoconf/toolchain_windows.m4 b/common/autoconf/toolchain_windows.m4 index e5d4fff38f9..f97713f952f 100644 --- a/common/autoconf/toolchain_windows.m4 +++ b/common/autoconf/toolchain_windows.m4 @@ -277,61 +277,3 @@ AC_DEFUN([TOOLCHAIN_SETUP_VISUAL_STUDIO_ENV], AC_MSG_RESULT([$MSVCR_DLL]) BASIC_FIXUP_PATH(MSVCR_DLL) ]) - - -# Setup the DXSDK paths -AC_DEFUN([TOOLCHAIN_SETUP_DXSDK], -[ - AC_ARG_WITH(dxsdk, [AS_HELP_STRING([--with-dxsdk], - [the DirectX SDK (Windows only) @<:@probed@:>@])]) - AC_ARG_WITH(dxsdk-lib, [AS_HELP_STRING([--with-dxsdk-lib], - [the DirectX SDK lib directory (Windows only) @<:@probed@:>@])]) - AC_ARG_WITH(dxsdk-include, [AS_HELP_STRING([--with-dxsdk-include], - [the DirectX SDK include directory (Windows only) @<:@probed@:>@])]) - - AC_MSG_CHECKING([for DirectX SDK]) - - if test "x$with_dxsdk" != x; then - dxsdk_path="$with_dxsdk" - elif test "x$DXSDK_DIR" != x; then - dxsdk_path="$DXSDK_DIR" - elif test -d "C:/DXSDK"; then - dxsdk_path="C:/DXSDK" - else - AC_MSG_ERROR([Could not find the DirectX SDK]) - fi - AC_MSG_RESULT([$dxsdk_path]) - BASIC_FIXUP_PATH(dxsdk_path) - - AC_MSG_CHECKING([for DirectX SDK lib dir]) - if test "x$with_dxsdk_lib" != x; then - DXSDK_LIB_PATH="$with_dxsdk_lib" - elif test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then - DXSDK_LIB_PATH="$dxsdk_path/Lib/x64" - else - DXSDK_LIB_PATH="$dxsdk_path/Lib" - fi - # dsound.lib is linked to in jsoundds - if test ! -f "$DXSDK_LIB_PATH/dsound.lib"; then - AC_MSG_ERROR([Invalid DirectX SDK lib dir]) - fi - AC_MSG_RESULT([$DXSDK_LIB_PATH]) - BASIC_FIXUP_PATH(DXSDK_LIB_PATH) - - AC_MSG_CHECKING([for DirectX SDK include dir]) - if test "x$with_dxsdk_include" != x; then - DXSDK_INCLUDE_PATH="$with_dxsdk_include" - else - DXSDK_INCLUDE_PATH="$dxsdk_path/Include" - fi - # dsound.h is included in jsoundds - if test ! -f "$DXSDK_INCLUDE_PATH/dsound.h"; then - AC_MSG_ERROR([Invalid DirectX SDK lib dir]) - fi - AC_MSG_RESULT([$DXSDK_INCLUDE_PATH]) - BASIC_FIXUP_PATH(DXSDK_INCLUDE_PATH) - - AC_SUBST(DXSDK_LIB_PATH) - AC_SUBST(DXSDK_INCLUDE_PATH) - LDFLAGS_JDK="$LDFLAGS_JDK -libpath:$DXSDK_LIB_PATH" -]) diff --git a/common/bin/hgforest.sh b/common/bin/hgforest.sh index 12cf0234b17..1dc50390b42 100644 --- a/common/bin/hgforest.sh +++ b/common/bin/hgforest.sh @@ -47,7 +47,7 @@ python="" bpython="" if [ "#!" = "$has_hash_bang" ] ; then - python="`head -n 1 ${whichhg} | cut -b 3-`" + python="`head -n 1 ${whichhg} | cut -b 3- | sed -e 's/^[ \t]*//;s/[ \t]*$//'`" bpython="`basename "$python"`" fi diff --git a/corba/.hgtags b/corba/.hgtags index f96b90eb232..e24845b3555 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -228,3 +228,4 @@ a013024b07475782f1fa8e196e950b34b4077663 jdk8-b101 d411c60a8c2fe8fdc572af907775e90f7eefd513 jdk8-b104 4e38de7c767e34104fa147b5b346d9fe6b731279 jdk8-b105 2e3a056c84a71eba78945c18b05397858ffd7ad0 jdk8-b106 +23fc34133152692b725db4bd617b4c8dfd6ccb05 jdk8-b107 diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java index fc1ffc70197..63578b9c3d1 100644 --- a/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java +++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/DefaultSocketFactoryImpl.java @@ -32,6 +32,7 @@ import java.net.SocketException; import java.net.ServerSocket; import java.nio.channels.SocketChannel; import java.nio.channels.ServerSocketChannel; +import java.security.PrivilegedAction; import com.sun.corba.se.pept.transport.Acceptor; @@ -44,6 +45,22 @@ public class DefaultSocketFactoryImpl implements ORBSocketFactory { private ORB orb; + private static final boolean keepAlive; + + static { + keepAlive = java.security.AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public Boolean run () { + String value = + System.getProperty("com.sun.CORBA.transport.enableTcpKeepAlive"); + if (value != null) + return new Boolean(!"false".equalsIgnoreCase(value)); + + return Boolean.FALSE; + } + }); + } public void setORB(ORB orb) { @@ -85,6 +102,9 @@ public class DefaultSocketFactoryImpl // Disable Nagle's algorithm (i.e., always send immediately). socket.setTcpNoDelay(true); + if (keepAlive) + socket.setKeepAlive(true); + return socket; } @@ -95,6 +115,8 @@ public class DefaultSocketFactoryImpl { // Disable Nagle's algorithm (i.e., always send immediately). socket.setTcpNoDelay(true); + if (keepAlive) + socket.setKeepAlive(true); } } diff --git a/hotspot/.hgtags b/hotspot/.hgtags index bc3aba45318..370ade6688d 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -375,3 +375,5 @@ acac3bde66b2c22791c257a8d99611d6d08c6713 jdk8-b105 18b4798adbc42c6fa16f5ecb7d5cd3ca130754bf hs25-b48 aed585cafc0d9655726af6d1e1081d1c94cb3b5c jdk8-b106 50794d8ac11c9579b41dec4de23b808fef9f34a1 hs25-b49 +5b7f90aab3ad25a25b75b7b2bb18d5ae23d8231c jdk8-b107 +a09fe9d1e016c285307507a5793bc4fa6215e9c9 hs25-b50 diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version index 15223e843df..e1572121149 100644 --- a/hotspot/make/hotspot_version +++ b/hotspot/make/hotspot_version @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013 HS_MAJOR_VER=25 HS_MINOR_VER=0 -HS_BUILD_NUMBER=49 +HS_BUILD_NUMBER=50 JDK_MAJOR_VER=1 JDK_MINOR_VER=8 diff --git a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp index 093be806072..e4fe6bb00a4 100644 --- a/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp +++ b/hotspot/src/cpu/sparc/vm/c2_globals_sparc.hpp @@ -57,6 +57,7 @@ define_pd_global(intx, RegisterCostAreaRatio, 12000); define_pd_global(bool, UseTLAB, true); define_pd_global(bool, ResizeTLAB, true); define_pd_global(intx, LoopUnrollLimit, 60); // Design center runs on 1.3.1 +define_pd_global(intx, MinJumpTableSize, 5); // Peephole and CISC spilling both break the graph, and so makes the // scheduler sick. diff --git a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp index d49bec21fe7..a45bd9624e5 100644 --- a/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp +++ b/hotspot/src/cpu/x86/vm/c2_globals_x86.hpp @@ -30,7 +30,6 @@ // Sets the default values for platform dependent flags used by the server compiler. // (see c2_globals.hpp). Alpha-sorted. - define_pd_global(bool, BackgroundCompilation, true); define_pd_global(bool, UseTLAB, true); define_pd_global(bool, ResizeTLAB, true); @@ -52,6 +51,7 @@ define_pd_global(intx, OnStackReplacePercentage, 140); define_pd_global(intx, ConditionalMoveLimit, 3); define_pd_global(intx, FLOATPRESSURE, 6); define_pd_global(intx, FreqInlineSize, 325); +define_pd_global(intx, MinJumpTableSize, 10); #ifdef AMD64 define_pd_global(intx, INTPRESSURE, 13); define_pd_global(intx, InteriorEntryAlignment, 16); diff --git a/hotspot/src/share/vm/ci/ciArray.cpp b/hotspot/src/share/vm/ci/ciArray.cpp index 584b1aeb50f..fdcc63a0dec 100644 --- a/hotspot/src/share/vm/ci/ciArray.cpp +++ b/hotspot/src/share/vm/ci/ciArray.cpp @@ -24,13 +24,92 @@ #include "precompiled.hpp" #include "ci/ciArray.hpp" +#include "ci/ciArrayKlass.hpp" +#include "ci/ciConstant.hpp" #include "ci/ciKlass.hpp" #include "ci/ciUtilities.hpp" +#include "oops/objArrayOop.hpp" +#include "oops/typeArrayOop.hpp" // ciArray // // This class represents an arrayOop in the HotSpot virtual // machine. +static BasicType fixup_element_type(BasicType bt) { + if (bt == T_ARRAY) return T_OBJECT; + if (bt == T_BOOLEAN) return T_BYTE; + return bt; +} + +ciConstant ciArray::element_value_impl(BasicType elembt, + arrayOop ary, + int index) { + if (ary == NULL) + return ciConstant(); + assert(ary->is_array(), ""); + if (index < 0 || index >= ary->length()) + return ciConstant(); + ArrayKlass* ak = (ArrayKlass*) ary->klass(); + BasicType abt = ak->element_type(); + if (fixup_element_type(elembt) != + fixup_element_type(abt)) + return ciConstant(); + switch (elembt) { + case T_ARRAY: + case T_OBJECT: + { + assert(ary->is_objArray(), ""); + objArrayOop objary = (objArrayOop) ary; + oop elem = objary->obj_at(index); + ciEnv* env = CURRENT_ENV; + ciObject* box = env->get_object(elem); + return ciConstant(T_OBJECT, box); + } + } + assert(ary->is_typeArray(), ""); + typeArrayOop tary = (typeArrayOop) ary; + jint value = 0; + switch (elembt) { + case T_LONG: return ciConstant(tary->long_at(index)); + case T_FLOAT: return ciConstant(tary->float_at(index)); + case T_DOUBLE: return ciConstant(tary->double_at(index)); + default: return ciConstant(); + case T_BYTE: value = tary->byte_at(index); break; + case T_BOOLEAN: value = tary->byte_at(index) & 1; break; + case T_SHORT: value = tary->short_at(index); break; + case T_CHAR: value = tary->char_at(index); break; + case T_INT: value = tary->int_at(index); break; + } + return ciConstant(elembt, value); +} + +// ------------------------------------------------------------------ +// ciArray::element_value +// +// Current value of an element. +// Returns T_ILLEGAL if there is no element at the given index. +ciConstant ciArray::element_value(int index) { + BasicType elembt = element_basic_type(); + GUARDED_VM_ENTRY( + return element_value_impl(elembt, get_arrayOop(), index); + ) +} + +// ------------------------------------------------------------------ +// ciArray::element_value_by_offset +// +// Current value of an element at the specified offset. +// Returns T_ILLEGAL if there is no element at the given offset. +ciConstant ciArray::element_value_by_offset(intptr_t element_offset) { + BasicType elembt = element_basic_type(); + intptr_t shift = exact_log2(type2aelembytes(elembt)); + intptr_t header = arrayOopDesc::base_offset_in_bytes(elembt); + intptr_t index = (element_offset - header) >> shift; + intptr_t offset = header + ((intptr_t)index << shift); + if (offset != element_offset || index != (jint)index) + return ciConstant(); + return element_value((jint) index); +} // ------------------------------------------------------------------ // ciArray::print_impl diff --git a/hotspot/src/share/vm/ci/ciArray.hpp b/hotspot/src/share/vm/ci/ciArray.hpp index 440e407a510..c5c86265d61 100644 --- a/hotspot/src/share/vm/ci/ciArray.hpp +++ b/hotspot/src/share/vm/ci/ciArray.hpp @@ -25,6 +25,8 @@ #ifndef SHARE_VM_CI_CIARRAY_HPP #define SHARE_VM_CI_CIARRAY_HPP +#include "ci/ciArrayKlass.hpp" +#include "ci/ciConstant.hpp" #include "ci/ciObject.hpp" #include "oops/arrayOop.hpp" #include "oops/objArrayOop.hpp" @@ -45,15 +47,30 @@ protected: ciArray(ciKlass* klass, int len) : ciObject(klass), _length(len) {} - arrayOop get_arrayOop() { return (arrayOop)get_oop(); } + arrayOop get_arrayOop() const { return (arrayOop)get_oop(); } const char* type_string() { return "ciArray"; } void print_impl(outputStream* st); + ciConstant element_value_impl(BasicType elembt, arrayOop ary, int index); + public: int length() { return _length; } + // Convenience routines. + ciArrayKlass* array_type() { return klass()->as_array_klass(); } + ciType* element_type() { return array_type()->element_type(); } + BasicType element_basic_type() { return element_type()->basic_type(); } + + // Current value of an element. + // Returns T_ILLEGAL if there is no element at the given index. + ciConstant element_value(int index); + + // Current value of an element at the specified offset. + // Returns T_ILLEGAL if there is no element at the given offset. + ciConstant element_value_by_offset(intptr_t element_offset); + // What kind of ciObject is this? bool is_array() { return true; } bool is_java_object() { return true; } diff --git a/hotspot/src/share/vm/ci/ciConstant.hpp b/hotspot/src/share/vm/ci/ciConstant.hpp index 8cdc893fd2b..7a72a7de1e5 100644 --- a/hotspot/src/share/vm/ci/ciConstant.hpp +++ b/hotspot/src/share/vm/ci/ciConstant.hpp @@ -41,7 +41,6 @@ private: union { jint _int; jlong _long; - jint _long_half[2]; jfloat _float; jdouble _double; ciObject* _object; @@ -111,6 +110,20 @@ public: return _value._object; } + bool is_null_or_zero() const { + if (!is_java_primitive(basic_type())) { + return as_object()->is_null_object(); + } else if (type2size[basic_type()] == 1) { + // treat float bits as int, to avoid comparison with -0 and NaN + return (_value._int == 0); + } else if (type2size[basic_type()] == 2) { + // treat double bits as long, to avoid comparison with -0 and NaN + return (_value._long == 0); + } else { + return false; + } + } + // Debugging output void print(); }; diff --git a/hotspot/src/share/vm/ci/ciField.cpp b/hotspot/src/share/vm/ci/ciField.cpp index fe967554c3a..1a711ae522a 100644 --- a/hotspot/src/share/vm/ci/ciField.cpp +++ b/hotspot/src/share/vm/ci/ciField.cpp @@ -189,12 +189,14 @@ void ciField::initialize_from(fieldDescriptor* fd) { _holder = CURRENT_ENV->get_instance_klass(fd->field_holder()); // Check to see if the field is constant. - if (_holder->is_initialized() && this->is_final()) { + bool is_final = this->is_final(); + bool is_stable = FoldStableValues && this->is_stable(); + if (_holder->is_initialized() && (is_final || is_stable)) { if (!this->is_static()) { // A field can be constant if it's a final static field or if // it's a final non-static field of a trusted class (classes in // java.lang.invoke and sun.invoke packages and subpackages). - if (trust_final_non_static_fields(_holder)) { + if (is_stable || trust_final_non_static_fields(_holder)) { _is_constant = true; return; } @@ -227,7 +229,6 @@ void ciField::initialize_from(fieldDescriptor* fd) { Handle mirror = k->java_mirror(); - _is_constant = true; switch(type()->basic_type()) { case T_BYTE: _constant_value = ciConstant(type()->basic_type(), mirror->byte_field(_offset)); @@ -273,6 +274,12 @@ void ciField::initialize_from(fieldDescriptor* fd) { } } } + if (is_stable && _constant_value.is_null_or_zero()) { + // It is not a constant after all; treat it as uninitialized. + _is_constant = false; + } else { + _is_constant = true; + } } else { _is_constant = false; } @@ -373,8 +380,11 @@ void ciField::print() { tty->print(" signature="); _signature->print_symbol(); tty->print(" offset=%d type=", _offset); - if (_type != NULL) _type->print_name(); - else tty->print("(reference)"); + if (_type != NULL) + _type->print_name(); + else + tty->print("(reference)"); + tty->print(" flags=%04x", flags().as_int()); tty->print(" is_constant=%s", bool_to_str(_is_constant)); if (_is_constant && is_static()) { tty->print(" constant_value="); diff --git a/hotspot/src/share/vm/ci/ciField.hpp b/hotspot/src/share/vm/ci/ciField.hpp index ff96c99313c..81af9ca79a9 100644 --- a/hotspot/src/share/vm/ci/ciField.hpp +++ b/hotspot/src/share/vm/ci/ciField.hpp @@ -139,7 +139,10 @@ public: // non-constant fields. These are java.lang.System.in // and java.lang.System.out. Abomination. // - // Note: the check for case 4 is not yet implemented. + // A field is also considered constant if it is marked @Stable + // and is non-null (or non-zero, if a primitive). + // For non-static fields, the null/zero check must be + // arranged by the user, as constant_value().is_null_or_zero(). bool is_constant() { return _is_constant; } // Get the constant value of this field. @@ -173,6 +176,7 @@ public: bool is_protected () { return flags().is_protected(); } bool is_static () { return flags().is_static(); } bool is_final () { return flags().is_final(); } + bool is_stable () { return flags().is_stable(); } bool is_volatile () { return flags().is_volatile(); } bool is_transient () { return flags().is_transient(); } diff --git a/hotspot/src/share/vm/ci/ciFlags.hpp b/hotspot/src/share/vm/ci/ciFlags.hpp index 6dc50d25a60..87e19466f27 100644 --- a/hotspot/src/share/vm/ci/ciFlags.hpp +++ b/hotspot/src/share/vm/ci/ciFlags.hpp @@ -59,6 +59,7 @@ public: bool is_interface () const { return (_flags & JVM_ACC_INTERFACE ) != 0; } bool is_abstract () const { return (_flags & JVM_ACC_ABSTRACT ) != 0; } bool is_strict () const { return (_flags & JVM_ACC_STRICT ) != 0; } + bool is_stable () const { return (_flags & JVM_ACC_FIELD_STABLE) != 0; } // Conversion jint as_int() { return _flags; } diff --git a/hotspot/src/share/vm/ci/ciInstance.cpp b/hotspot/src/share/vm/ci/ciInstance.cpp index a74eb04f4a7..8b48b1b3706 100644 --- a/hotspot/src/share/vm/ci/ciInstance.cpp +++ b/hotspot/src/share/vm/ci/ciInstance.cpp @@ -127,6 +127,8 @@ ciConstant ciInstance::field_value(ciField* field) { ciConstant ciInstance::field_value_by_offset(int field_offset) { ciInstanceKlass* ik = klass()->as_instance_klass(); ciField* field = ik->get_field_by_offset(field_offset, false); + if (field == NULL) + return ciConstant(); // T_ILLEGAL return field_value(field); } diff --git a/hotspot/src/share/vm/ci/ciTypeArray.cpp b/hotspot/src/share/vm/ci/ciTypeArray.cpp index d4a6eff6f41..2d013e21c0e 100644 --- a/hotspot/src/share/vm/ci/ciTypeArray.cpp +++ b/hotspot/src/share/vm/ci/ciTypeArray.cpp @@ -39,5 +39,10 @@ jchar ciTypeArray::char_at(int index) { VM_ENTRY_MARK; assert(index >= 0 && index < length(), "out of range"); - return get_typeArrayOop()->char_at(index); + jchar c = get_typeArrayOop()->char_at(index); +#ifdef ASSERT + jchar d = element_value(index).as_char(); + assert(c == d, ""); +#endif //ASSERT + return c; } diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp index 0705c5f14d6..8972bceb434 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.cpp +++ b/hotspot/src/share/vm/classfile/classFileParser.cpp @@ -1774,6 +1774,10 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d if (_location != _in_method) break; // only allow for methods if (!privileged) break; // only allow in privileged code return _method_LambdaForm_Hidden; + case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_invoke_Stable_signature): + if (_location != _in_field) break; // only allow for fields + if (!privileged) break; // only allow in privileged code + return _field_Stable; case vmSymbols::VM_SYMBOL_ENUM_NAME(sun_misc_Contended_signature): if (_location != _in_field && _location != _in_class) break; // only allow for fields and classes if (!EnableContended || (RestrictContended && !privileged)) break; // honor privileges @@ -1786,6 +1790,8 @@ ClassFileParser::AnnotationCollector::annotation_index(ClassLoaderData* loader_d void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) { if (is_contended()) f->set_contended_group(contended_group()); + if (is_stable()) + f->set_stable(true); } ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() { diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp index 1b5ed30c5a6..02a4ce20dd3 100644 --- a/hotspot/src/share/vm/classfile/classFileParser.hpp +++ b/hotspot/src/share/vm/classfile/classFileParser.hpp @@ -125,6 +125,7 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { _method_LambdaForm_Compiled, _method_LambdaForm_Hidden, _sun_misc_Contended, + _field_Stable, _annotation_LIMIT }; const Location _location; @@ -143,14 +144,23 @@ class ClassFileParser VALUE_OBJ_CLASS_SPEC { assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); _annotations_present |= nth_bit((int)id); } + + void remove_annotation(ID id) { + assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob"); + _annotations_present &= ~nth_bit((int)id); + } + // Report if the annotation is present. - bool has_any_annotations() { return _annotations_present != 0; } - bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; } + bool has_any_annotations() const { return _annotations_present != 0; } + bool has_annotation(ID id) const { return (nth_bit((int)id) & _annotations_present) != 0; } void set_contended_group(u2 group) { _contended_group = group; } - u2 contended_group() { return _contended_group; } + u2 contended_group() const { return _contended_group; } - bool is_contended() { return has_annotation(_sun_misc_Contended); } + bool is_contended() const { return has_annotation(_sun_misc_Contended); } + + void set_stable(bool stable) { set_annotation(_field_Stable); } + bool is_stable() const { return has_annotation(_field_Stable); } }; // This class also doubles as a holder for metadata cleanup. diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp index 067cf503305..f1758f86654 100644 --- a/hotspot/src/share/vm/classfile/vmSymbols.hpp +++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp @@ -270,6 +270,7 @@ template(java_lang_invoke_LambdaForm, "java/lang/invoke/LambdaForm") \ template(java_lang_invoke_ForceInline_signature, "Ljava/lang/invoke/ForceInline;") \ template(java_lang_invoke_DontInline_signature, "Ljava/lang/invoke/DontInline;") \ + template(sun_invoke_Stable_signature, "Lsun/invoke/Stable;") \ template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \ template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;") \ template(java_lang_invoke_MagicLambdaImpl, "java/lang/invoke/MagicLambdaImpl") \ diff --git a/hotspot/src/share/vm/oops/fieldInfo.hpp b/hotspot/src/share/vm/oops/fieldInfo.hpp index 5da8ed9628a..6763c42d127 100644 --- a/hotspot/src/share/vm/oops/fieldInfo.hpp +++ b/hotspot/src/share/vm/oops/fieldInfo.hpp @@ -240,6 +240,14 @@ class FieldInfo VALUE_OBJ_CLASS_SPEC { return (access_flags() & JVM_ACC_FIELD_INTERNAL) != 0; } + bool is_stable() const { + return (access_flags() & JVM_ACC_FIELD_STABLE) != 0; + } + void set_stable(bool z) { + if (z) _shorts[access_flags_offset] |= JVM_ACC_FIELD_STABLE; + else _shorts[access_flags_offset] &= ~JVM_ACC_FIELD_STABLE; + } + Symbol* lookup_symbol(int symbol_index) const { assert(is_internal(), "only internal fields"); return vmSymbols::symbol_at((vmSymbols::SID)symbol_index); diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp index 15d8befbbac..cf9a82092fd 100644 --- a/hotspot/src/share/vm/opto/c2_globals.hpp +++ b/hotspot/src/share/vm/opto/c2_globals.hpp @@ -421,7 +421,7 @@ product(bool, UseDivMod, true, \ "Use combined DivMod instruction if available") \ \ - product(intx, MinJumpTableSize, 18, \ + product_pd(intx, MinJumpTableSize, \ "Minimum number of targets in a generated jump table") \ \ product(intx, MaxJumpTableSize, 65000, \ @@ -448,6 +448,9 @@ product(bool, EliminateAutoBox, true, \ "Control optimizations for autobox elimination") \ \ + experimental(bool, UseImplicitStableValues, false, \ + "Mark well-known stable fields as such (e.g. String.value)") \ + \ product(intx, AutoBoxCacheMax, 128, \ "Sets max value cached by the java.lang.Integer autobox cache") \ \ diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp index b426bcce1a2..8d7e6c9e102 100644 --- a/hotspot/src/share/vm/opto/compile.cpp +++ b/hotspot/src/share/vm/opto/compile.cpp @@ -1297,6 +1297,10 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const { // Array pointers need some flattening const TypeAryPtr *ta = tj->isa_aryptr(); + if (ta && ta->is_stable()) { + // Erase stability property for alias analysis. + tj = ta = ta->cast_to_stable(false); + } if( ta && is_known_inst ) { if ( offset != Type::OffsetBot && offset > arrayOopDesc::length_offset_in_bytes() ) { @@ -1497,6 +1501,7 @@ void Compile::AliasType::Init(int i, const TypePtr* at) { _index = i; _adr_type = at; _field = NULL; + _element = NULL; _is_rewritable = true; // default const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL; if (atoop != NULL && atoop->is_known_instance()) { @@ -1615,6 +1620,16 @@ Compile::AliasType* Compile::find_alias_type(const TypePtr* adr_type, bool no_cr && flat->is_instptr()->klass() == env()->Class_klass()) alias_type(idx)->set_rewritable(false); } + if (flat->isa_aryptr()) { +#ifdef ASSERT + const int header_size_min = arrayOopDesc::base_offset_in_bytes(T_BYTE); + // (T_BYTE has the weakest alignment and size restrictions...) + assert(flat->offset() < header_size_min, "array body reference must be OffsetBot"); +#endif + if (flat->offset() == TypePtr::OffsetBot) { + alias_type(idx)->set_element(flat->is_aryptr()->elem()); + } + } if (flat->isa_klassptr()) { if (flat->offset() == in_bytes(Klass::super_check_offset_offset())) alias_type(idx)->set_rewritable(false); @@ -1677,7 +1692,7 @@ Compile::AliasType* Compile::alias_type(ciField* field) { else t = TypeOopPtr::make_from_klass_raw(field->holder()); AliasType* atp = alias_type(t->add_offset(field->offset_in_bytes()), field); - assert(field->is_final() == !atp->is_rewritable(), "must get the rewritable bits correct"); + assert((field->is_final() || field->is_stable()) == !atp->is_rewritable(), "must get the rewritable bits correct"); return atp; } diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp index 60787464bd0..8d862c24125 100644 --- a/hotspot/src/share/vm/opto/compile.hpp +++ b/hotspot/src/share/vm/opto/compile.hpp @@ -72,6 +72,7 @@ class Scope; class StartNode; class SafePointNode; class JVMState; +class Type; class TypeData; class TypePtr; class TypeOopPtr; @@ -119,6 +120,7 @@ class Compile : public Phase { int _index; // unique index, used with MergeMemNode const TypePtr* _adr_type; // normalized address type ciField* _field; // relevant instance field, or null if none + const Type* _element; // relevant array element type, or null if none bool _is_rewritable; // false if the memory is write-once only int _general_index; // if this is type is an instance, the general // type that this is an instance of @@ -129,6 +131,7 @@ class Compile : public Phase { int index() const { return _index; } const TypePtr* adr_type() const { return _adr_type; } ciField* field() const { return _field; } + const Type* element() const { return _element; } bool is_rewritable() const { return _is_rewritable; } bool is_volatile() const { return (_field ? _field->is_volatile() : false); } int general_index() const { return (_general_index != 0) ? _general_index : _index; } @@ -137,7 +140,14 @@ class Compile : public Phase { void set_field(ciField* f) { assert(!_field,""); _field = f; - if (f->is_final()) _is_rewritable = false; + if (f->is_final() || f->is_stable()) { + // In the case of @Stable, multiple writes are possible but may be assumed to be no-ops. + _is_rewritable = false; + } + } + void set_element(const Type* e) { + assert(_element == NULL, ""); + _element = e; } void print_on(outputStream* st) PRODUCT_RETURN; diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp index 18772dfd0a8..dcdd104ee72 100644 --- a/hotspot/src/share/vm/opto/graphKit.cpp +++ b/hotspot/src/share/vm/opto/graphKit.cpp @@ -3825,8 +3825,13 @@ Node* GraphKit::load_String_value(Node* ctrl, Node* str) { TypeAry::make(TypeInt::CHAR,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, 0); int value_field_idx = C->get_alias_index(value_field_type); - return make_load(ctrl, basic_plus_adr(str, str, value_offset), - value_type, T_OBJECT, value_field_idx); + Node* load = make_load(ctrl, basic_plus_adr(str, str, value_offset), + value_type, T_OBJECT, value_field_idx); + // String.value field is known to be @Stable. + if (UseImplicitStableValues) { + load = cast_array_to_stable(load, value_type); + } + return load; } void GraphKit::store_String_offset(Node* ctrl, Node* str, Node* value) { @@ -3844,9 +3849,6 @@ void GraphKit::store_String_value(Node* ctrl, Node* str, Node* value) { const TypeInstPtr* string_type = TypeInstPtr::make(TypePtr::NotNull, C->env()->String_klass(), false, NULL, 0); const TypePtr* value_field_type = string_type->add_offset(value_offset); - const TypeAryPtr* value_type = TypeAryPtr::make(TypePtr::NotNull, - TypeAry::make(TypeInt::CHAR,TypeInt::POS), - ciTypeArrayKlass::make(T_CHAR), true, 0); int value_field_idx = C->get_alias_index(value_field_type); store_to_memory(ctrl, basic_plus_adr(str, value_offset), value, T_OBJECT, value_field_idx); @@ -3861,3 +3863,9 @@ void GraphKit::store_String_length(Node* ctrl, Node* str, Node* value) { store_to_memory(ctrl, basic_plus_adr(str, count_offset), value, T_INT, count_field_idx); } + +Node* GraphKit::cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type) { + // Reify the property as a CastPP node in Ideal graph to comply with monotonicity + // assumption of CCP analysis. + return _gvn.transform(new(C) CastPPNode(ary, ary_type->cast_to_stable(true))); +} diff --git a/hotspot/src/share/vm/opto/graphKit.hpp b/hotspot/src/share/vm/opto/graphKit.hpp index e9d102cb6c5..1fd4e86d2e7 100644 --- a/hotspot/src/share/vm/opto/graphKit.hpp +++ b/hotspot/src/share/vm/opto/graphKit.hpp @@ -836,6 +836,9 @@ class GraphKit : public Phase { // Insert a loop predicate into the graph void add_predicate(int nargs = 0); void add_predicate_impl(Deoptimization::DeoptReason reason, int nargs); + + // Produce new array node of stable type + Node* cast_array_to_stable(Node* ary, const TypeAryPtr* ary_type); }; // Helper class to support building of control flow branches. Upon diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp index 60525d73ef7..f7e09c3f89f 100644 --- a/hotspot/src/share/vm/opto/library_call.cpp +++ b/hotspot/src/share/vm/opto/library_call.cpp @@ -1280,6 +1280,11 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar const TypeAry* target_array_type = TypeAry::make(TypeInt::CHAR, TypeInt::make(0, target_length, Type::WidenMin)); const TypeAryPtr* target_type = TypeAryPtr::make(TypePtr::BotPTR, target_array_type, target_array->klass(), true, Type::OffsetBot); + // String.value field is known to be @Stable. + if (UseImplicitStableValues) { + target = cast_array_to_stable(target, target_type); + } + IdealKit kit(this, false, true); #define __ kit. Node* zero = __ ConI(0); diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp index aa03b5ff6c5..a91c63abc9b 100644 --- a/hotspot/src/share/vm/opto/memnode.cpp +++ b/hotspot/src/share/vm/opto/memnode.cpp @@ -962,6 +962,19 @@ uint LoadNode::hash() const { return (uintptr_t)in(Control) + (uintptr_t)in(Memory) + (uintptr_t)in(Address); } +static bool skip_through_membars(Compile::AliasType* atp, const TypeInstPtr* tp, bool eliminate_boxing) { + if ((atp != NULL) && (atp->index() >= Compile::AliasIdxRaw)) { + bool non_volatile = (atp->field() != NULL) && !atp->field()->is_volatile(); + bool is_stable_ary = FoldStableValues && + (tp != NULL) && (tp->isa_aryptr() != NULL) && + tp->isa_aryptr()->is_stable(); + + return (eliminate_boxing && non_volatile) || is_stable_ary; + } + + return false; +} + //---------------------------can_see_stored_value------------------------------ // This routine exists to make sure this set of tests is done the same // everywhere. We need to make a coordinated change: first LoadNode::Ideal @@ -976,11 +989,9 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { const TypeInstPtr* tp = phase->type(ld_adr)->isa_instptr(); Compile::AliasType* atp = (tp != NULL) ? phase->C->alias_type(tp) : NULL; // This is more general than load from boxing objects. - if (phase->C->eliminate_boxing() && (atp != NULL) && - (atp->index() >= Compile::AliasIdxRaw) && - (atp->field() != NULL) && !atp->field()->is_volatile()) { + if (skip_through_membars(atp, tp, phase->C->eliminate_boxing())) { uint alias_idx = atp->index(); - bool final = atp->field()->is_final(); + bool final = !atp->is_rewritable(); Node* result = NULL; Node* current = st; // Skip through chains of MemBarNodes checking the MergeMems for @@ -1015,7 +1026,6 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const { } } - // Loop around twice in the case Load -> Initialize -> Store. // (See PhaseIterGVN::add_users_to_worklist, which knows about this case.) for (int trip = 0; trip <= 1; trip++) { @@ -1577,6 +1587,40 @@ LoadNode::load_array_final_field(const TypeKlassPtr *tkls, return NULL; } +// Try to constant-fold a stable array element. +static const Type* fold_stable_ary_elem(const TypeAryPtr* ary, int off, BasicType loadbt) { + assert(ary->is_stable(), "array should be stable"); + + if (ary->const_oop() != NULL) { + // Decode the results of GraphKit::array_element_address. + ciArray* aobj = ary->const_oop()->as_array(); + ciConstant con = aobj->element_value_by_offset(off); + + if (con.basic_type() != T_ILLEGAL && !con.is_null_or_zero()) { + const Type* con_type = Type::make_from_constant(con); + if (con_type != NULL) { + if (con_type->isa_aryptr()) { + // Join with the array element type, in case it is also stable. + int dim = ary->stable_dimension(); + con_type = con_type->is_aryptr()->cast_to_stable(true, dim-1); + } + if (loadbt == T_NARROWOOP && con_type->isa_oopptr()) { + con_type = con_type->make_narrowoop(); + } +#ifndef PRODUCT + if (TraceIterativeGVN) { + tty->print("FoldStableValues: array element [off=%d]: con_type=", off); + con_type->dump(); tty->cr(); + } +#endif //PRODUCT + return con_type; + } + } + } + + return NULL; +} + //------------------------------Value----------------------------------------- const Type *LoadNode::Value( PhaseTransform *phase ) const { // Either input is TOP ==> the result is TOP @@ -1591,8 +1635,31 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { Compile* C = phase->C; // Try to guess loaded type from pointer type - if (tp->base() == Type::AryPtr) { - const Type *t = tp->is_aryptr()->elem(); + if (tp->isa_aryptr()) { + const TypeAryPtr* ary = tp->is_aryptr(); + const Type *t = ary->elem(); + + // Determine whether the reference is beyond the header or not, by comparing + // the offset against the offset of the start of the array's data. + // Different array types begin at slightly different offsets (12 vs. 16). + // We choose T_BYTE as an example base type that is least restrictive + // as to alignment, which will therefore produce the smallest + // possible base offset. + const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); + const bool off_beyond_header = ((uint)off >= (uint)min_base_off); + + // Try to constant-fold a stable array element. + if (FoldStableValues && ary->is_stable()) { + // Make sure the reference is not into the header + if (off_beyond_header && off != Type::OffsetBot) { + assert(adr->is_AddP() && adr->in(AddPNode::Offset)->is_Con(), "offset is a constant"); + const Type* con_type = fold_stable_ary_elem(ary, off, memory_type()); + if (con_type != NULL) { + return con_type; + } + } + } + // Don't do this for integer types. There is only potential profit if // the element type t is lower than _type; that is, for int types, if _type is // more restrictive than t. This only happens here if one is short and the other @@ -1613,14 +1680,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const { && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) { // t might actually be lower than _type, if _type is a unique // concrete subclass of abstract class t. - // Make sure the reference is not into the header, by comparing - // the offset against the offset of the start of the array's data. - // Different array types begin at slightly different offsets (12 vs. 16). - // We choose T_BYTE as an example base type that is least restrictive - // as to alignment, which will therefore produce the smallest - // possible base offset. - const int min_base_off = arrayOopDesc::base_offset_in_bytes(T_BYTE); - if ((uint)off >= (uint)min_base_off) { // is the offset beyond the header? + if (off_beyond_header) { // is the offset beyond the header? const Type* jt = t->join(_type); // In any case, do not allow the join, per se, to empty out the type. if (jt->empty() && !t->empty()) { diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp index 91025bf56fb..ea01b08475e 100644 --- a/hotspot/src/share/vm/opto/parse.hpp +++ b/hotspot/src/share/vm/opto/parse.hpp @@ -518,7 +518,7 @@ class Parse : public GraphKit { // loading from a constant field or the constant pool // returns false if push failed (non-perm field constants only, not ldcs) - bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false); + bool push_constant(ciConstant con, bool require_constant = false, bool is_autobox_cache = false, const Type* basic_type = NULL); // implementation of object creation bytecodes void emit_guard_for_new(ciInstanceKlass* klass); diff --git a/hotspot/src/share/vm/opto/parse3.cpp b/hotspot/src/share/vm/opto/parse3.cpp index 28eb0580bad..8c545f3ece5 100644 --- a/hotspot/src/share/vm/opto/parse3.cpp +++ b/hotspot/src/share/vm/opto/parse3.cpp @@ -147,7 +147,15 @@ void Parse::do_field_access(bool is_get, bool is_field) { void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { // Does this field have a constant value? If so, just push the value. if (field->is_constant()) { - // final field + // final or stable field + const Type* stable_type = NULL; + if (FoldStableValues && field->is_stable()) { + stable_type = Type::get_const_type(field->type()); + if (field->type()->is_array_klass()) { + int stable_dimension = field->type()->as_array_klass()->dimension(); + stable_type = stable_type->is_aryptr()->cast_to_stable(true, stable_dimension); + } + } if (field->is_static()) { // final static field if (C->eliminate_boxing()) { @@ -167,11 +175,10 @@ void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { } } } - if (push_constant(field->constant_value())) + if (push_constant(field->constant_value(), false, false, stable_type)) return; - } - else { - // final non-static field + } else { + // final or stable non-static field // Treat final non-static fields of trusted classes (classes in // java.lang.invoke and sun.invoke packages and subpackages) as // compile time constants. @@ -179,8 +186,12 @@ void Parse::do_get_xxx(Node* obj, ciField* field, bool is_field) { const TypeOopPtr* oop_ptr = obj->bottom_type()->isa_oopptr(); ciObject* constant_oop = oop_ptr->const_oop(); ciConstant constant = field->constant_value_of(constant_oop); - if (push_constant(constant, true)) - return; + if (FoldStableValues && field->is_stable() && constant.is_null_or_zero()) { + // fall through to field load; the field is not yet initialized + } else { + if (push_constant(constant, true, false, stable_type)) + return; + } } } } @@ -301,7 +312,8 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { // Note the presence of writes to final non-static fields, so that we // can insert a memory barrier later on to keep the writes from floating // out of the constructor. - if (is_field && field->is_final()) { + // Any method can write a @Stable field; insert memory barriers after those also. + if (is_field && (field->is_final() || field->is_stable())) { set_wrote_final(true); // Preserve allocation ptr to create precedent edge to it in membar // generated on exit from constructor. @@ -314,35 +326,21 @@ void Parse::do_put_xxx(Node* obj, ciField* field, bool is_field) { } -bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache) { + +bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_autobox_cache, const Type* stable_type) { + const Type* con_type = Type::make_from_constant(constant, require_constant, is_autobox_cache); switch (constant.basic_type()) { - case T_BOOLEAN: push( intcon(constant.as_boolean()) ); break; - case T_INT: push( intcon(constant.as_int()) ); break; - case T_CHAR: push( intcon(constant.as_char()) ); break; - case T_BYTE: push( intcon(constant.as_byte()) ); break; - case T_SHORT: push( intcon(constant.as_short()) ); break; - case T_FLOAT: push( makecon(TypeF::make(constant.as_float())) ); break; - case T_DOUBLE: push_pair( makecon(TypeD::make(constant.as_double())) ); break; - case T_LONG: push_pair( longcon(constant.as_long()) ); break; case T_ARRAY: - case T_OBJECT: { + case T_OBJECT: // cases: // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) // An oop is not scavengable if it is in the perm gen. - ciObject* oop_constant = constant.as_object(); - if (oop_constant->is_null_object()) { - push( zerocon(T_OBJECT) ); - break; - } else if (require_constant || oop_constant->should_be_constant()) { - push( makecon(TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache)) ); - break; - } else { - // we cannot inline the oop, but we can use it later to narrow a type - return false; - } - } - case T_ILLEGAL: { + if (stable_type != NULL && con_type != NULL && con_type->isa_oopptr()) + con_type = con_type->join(stable_type); + break; + + case T_ILLEGAL: // Invalid ciConstant returned due to OutOfMemoryError in the CI assert(C->env()->failing(), "otherwise should not see this"); // These always occur because of object types; we are going to @@ -350,17 +348,16 @@ bool Parse::push_constant(ciConstant constant, bool require_constant, bool is_au push( zerocon(T_OBJECT) ); return false; } - default: - ShouldNotReachHere(); - return false; - } - // success + if (con_type == NULL) + // we cannot inline the oop, but we can use it later to narrow a type + return false; + + push_node(constant.basic_type(), makecon(con_type)); return true; } - //============================================================================= void Parse::do_anewarray() { bool will_link; diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp index fabcf1cad16..23e84a05d77 100644 --- a/hotspot/src/share/vm/opto/type.cpp +++ b/hotspot/src/share/vm/opto/type.cpp @@ -189,6 +189,38 @@ const Type* Type::get_typeflow_type(ciType* type) { } +//-----------------------make_from_constant------------------------------------ +const Type* Type::make_from_constant(ciConstant constant, + bool require_constant, bool is_autobox_cache) { + switch (constant.basic_type()) { + case T_BOOLEAN: return TypeInt::make(constant.as_boolean()); + case T_CHAR: return TypeInt::make(constant.as_char()); + case T_BYTE: return TypeInt::make(constant.as_byte()); + case T_SHORT: return TypeInt::make(constant.as_short()); + case T_INT: return TypeInt::make(constant.as_int()); + case T_LONG: return TypeLong::make(constant.as_long()); + case T_FLOAT: return TypeF::make(constant.as_float()); + case T_DOUBLE: return TypeD::make(constant.as_double()); + case T_ARRAY: + case T_OBJECT: + { + // cases: + // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) + // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) + // An oop is not scavengable if it is in the perm gen. + ciObject* oop_constant = constant.as_object(); + if (oop_constant->is_null_object()) { + return Type::get_zero_type(T_OBJECT); + } else if (require_constant || oop_constant->should_be_constant()) { + return TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache); + } + } + } + // Fall through to failure + return NULL; +} + + //------------------------------make------------------------------------------- // Create a simple Type, with default empty symbol sets. Then hashcons it // and look for an existing copy in the type dictionary. @@ -1824,12 +1856,12 @@ inline const TypeInt* normalize_array_size(const TypeInt* size) { } //------------------------------make------------------------------------------- -const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) { +const TypeAry* TypeAry::make(const Type* elem, const TypeInt* size, bool stable) { if (UseCompressedOops && elem->isa_oopptr()) { elem = elem->make_narrowoop(); } size = normalize_array_size(size); - return (TypeAry*)(new TypeAry(elem,size))->hashcons(); + return (TypeAry*)(new TypeAry(elem,size,stable))->hashcons(); } //------------------------------meet------------------------------------------- @@ -1850,7 +1882,8 @@ const Type *TypeAry::xmeet( const Type *t ) const { case Array: { // Meeting 2 arrays? const TypeAry *a = t->is_ary(); return TypeAry::make(_elem->meet(a->_elem), - _size->xmeet(a->_size)->is_int()); + _size->xmeet(a->_size)->is_int(), + _stable & a->_stable); } case Top: break; @@ -1863,7 +1896,7 @@ const Type *TypeAry::xmeet( const Type *t ) const { const Type *TypeAry::xdual() const { const TypeInt* size_dual = _size->dual()->is_int(); size_dual = normalize_array_size(size_dual); - return new TypeAry( _elem->dual(), size_dual); + return new TypeAry(_elem->dual(), size_dual, !_stable); } //------------------------------eq--------------------------------------------- @@ -1871,13 +1904,14 @@ const Type *TypeAry::xdual() const { bool TypeAry::eq( const Type *t ) const { const TypeAry *a = (const TypeAry*)t; return _elem == a->_elem && + _stable == a->_stable && _size == a->_size; } //------------------------------hash------------------------------------------- // Type-specific hashing function. int TypeAry::hash(void) const { - return (intptr_t)_elem + (intptr_t)_size; + return (intptr_t)_elem + (intptr_t)_size + (_stable ? 43 : 0); } //----------------------interface_vs_oop--------------------------------------- @@ -1894,6 +1928,7 @@ bool TypeAry::interface_vs_oop(const Type *t) const { //------------------------------dump2------------------------------------------ #ifndef PRODUCT void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const { + if (_stable) st->print("stable:"); _elem->dump2(d, depth, st); st->print("["); _size->dump2(d, depth, st); @@ -3457,11 +3492,39 @@ const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { assert(new_size != NULL, ""); new_size = narrow_size_type(new_size); if (new_size == size()) return this; - const TypeAry* new_ary = TypeAry::make(elem(), new_size); + const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable()); return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); } +//------------------------------cast_to_stable--------------------------------- +const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const { + if (stable_dimension <= 0 || (stable_dimension == 1 && stable == this->is_stable())) + return this; + + const Type* elem = this->elem(); + const TypePtr* elem_ptr = elem->make_ptr(); + + if (stable_dimension > 1 && elem_ptr != NULL && elem_ptr->isa_aryptr()) { + // If this is widened from a narrow oop, TypeAry::make will re-narrow it. + elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1); + } + + const TypeAry* new_ary = TypeAry::make(elem, size(), stable); + + return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); +} + +//-----------------------------stable_dimension-------------------------------- +int TypeAryPtr::stable_dimension() const { + if (!is_stable()) return 0; + int dim = 1; + const TypePtr* elem_ptr = elem()->make_ptr(); + if (elem_ptr != NULL && elem_ptr->isa_aryptr()) + dim += elem_ptr->is_aryptr()->stable_dimension(); + return dim; +} + //------------------------------eq--------------------------------------------- // Structural equality check for Type representations bool TypeAryPtr::eq( const Type *t ) const { @@ -3570,7 +3633,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { // Something like byte[int+] meets char[int+]. // This must fall to bottom, not (int[-128..65535])[int+]. instance_id = InstanceBot; - tary = TypeAry::make(Type::BOTTOM, tary->_size); + tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); } } else // Non integral arrays. // Must fall to bottom if exact klasses in upper lattice @@ -3584,7 +3647,7 @@ const Type *TypeAryPtr::xmeet( const Type *t ) const { (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { - tary = TypeAry::make(Type::BOTTOM, tary->_size); + tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot ); } diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp index 55d98bd5e51..d4832591843 100644 --- a/hotspot/src/share/vm/opto/type.hpp +++ b/hotspot/src/share/vm/opto/type.hpp @@ -372,6 +372,10 @@ public: // Mapping from CI type system to compiler type: static const Type* get_typeflow_type(ciType* type); + static const Type* make_from_constant(ciConstant constant, + bool require_constant = false, + bool is_autobox_cache = false); + private: // support arrays static const BasicType _basic_type[]; @@ -588,8 +592,8 @@ public: //------------------------------TypeAry---------------------------------------- // Class of Array Types class TypeAry : public Type { - TypeAry( const Type *elem, const TypeInt *size) : Type(Array), - _elem(elem), _size(size) {} + TypeAry(const Type* elem, const TypeInt* size, bool stable) : Type(Array), + _elem(elem), _size(size), _stable(stable) {} public: virtual bool eq( const Type *t ) const; virtual int hash() const; // Type specific hashing @@ -599,10 +603,11 @@ public: private: const Type *_elem; // Element type of array const TypeInt *_size; // Elements in array + const bool _stable; // Are elements @Stable? friend class TypeAryPtr; public: - static const TypeAry *make( const Type *elem, const TypeInt *size); + static const TypeAry* make(const Type* elem, const TypeInt* size, bool stable = false); virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. @@ -988,6 +993,7 @@ public: const TypeAry* ary() const { return _ary; } const Type* elem() const { return _ary->_elem; } const TypeInt* size() const { return _ary->_size; } + bool is_stable() const { return _ary->_stable; } bool is_autobox_cache() const { return _is_autobox_cache; } @@ -1011,6 +1017,9 @@ public: virtual const Type *xmeet( const Type *t ) const; virtual const Type *xdual() const; // Compute dual right now. + const TypeAryPtr* cast_to_stable(bool stable, int stable_dimension = 1) const; + int stable_dimension() const; + // Convenience common pre-built types. static const TypeAryPtr *RANGE; static const TypeAryPtr *OOPS; diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index c9bcbe1f4d3..7fdf668bac5 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3649,6 +3649,9 @@ class CommandLineFlags { experimental(bool, TrustFinalNonStaticFields, false, \ "trust final non-static declarations for constant folding") \ \ + experimental(bool, FoldStableValues, false, \ + "Private flag to control optimizations for stable variables") \ + \ develop(bool, TraceInvokeDynamic, false, \ "trace internal invoke dynamic operations") \ \ diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.hpp b/hotspot/src/share/vm/runtime/interfaceSupport.hpp index f995a4ee714..4d2ca5137ea 100644 --- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp +++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp @@ -471,16 +471,6 @@ class RuntimeHistogramElement : public HistogramElement { VM_ENTRY_BASE(result_type, header, thread) \ debug_only(VMEntryWrapper __vew;) -// Another special case for nmethod_entry_point so the nmethod that the -// interpreter is about to branch to doesn't get flushed before as we -// branch to it's interpreter_entry_point. Skip stress testing here too. -// Also we don't allow async exceptions because it is just too painful. -#define IRT_ENTRY_FOR_NMETHOD(result_type, header) \ - result_type header { \ - nmethodLocker _nmlock(nm); \ - ThreadInVMfromJavaNoAsyncException __tiv(thread); \ - VM_ENTRY_BASE(result_type, header, thread) - #define IRT_END } diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp index 99f9a3360f8..a3d3de99c91 100644 --- a/hotspot/src/share/vm/utilities/accessFlags.hpp +++ b/hotspot/src/share/vm/utilities/accessFlags.hpp @@ -78,11 +78,13 @@ enum { JVM_ACC_FIELD_ACCESS_WATCHED = 0x00002000, // field access is watched by JVMTI JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000, // field modification is watched by JVMTI JVM_ACC_FIELD_INTERNAL = 0x00000400, // internal field, same as JVM_ACC_ABSTRACT + JVM_ACC_FIELD_STABLE = 0x00000020, // @Stable field, same as JVM_ACC_SYNCHRONIZED JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature JVM_ACC_FIELD_INTERNAL_FLAGS = JVM_ACC_FIELD_ACCESS_WATCHED | JVM_ACC_FIELD_MODIFICATION_WATCHED | JVM_ACC_FIELD_INTERNAL | + JVM_ACC_FIELD_STABLE | JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE, // flags accepted by set_field_flags() @@ -148,6 +150,7 @@ class AccessFlags VALUE_OBJ_CLASS_SPEC { { return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; } bool on_stack() const { return (_flags & JVM_ACC_ON_STACK) != 0; } bool is_internal() const { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; } + bool is_stable() const { return (_flags & JVM_ACC_FIELD_STABLE) != 0; } bool field_has_generic_signature() const { return (_flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) != 0; } diff --git a/hotspot/test/gc/TestVerifyDuringStartup.java b/hotspot/test/gc/TestVerifyDuringStartup.java index f4ac347f80e..4ac32bf118e 100644 --- a/hotspot/test/gc/TestVerifyDuringStartup.java +++ b/hotspot/test/gc/TestVerifyDuringStartup.java @@ -48,7 +48,7 @@ public class TestVerifyDuringStartup { "-XX:+VerifyDuringStartup", "-version"}); - System.out.print("Testing:\n" + JDKToolFinder.getJDKTool("java")); + System.out.print("Testing:\n" + JDKToolFinder.getCurrentJDKTool("java")); for (int i = 0; i < vmOpts.size(); i += 1) { System.out.print(" " + vmOpts.get(i)); } diff --git a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java index 91ad6a8c8a9..a39abbd3626 100644 --- a/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java +++ b/hotspot/test/testlibrary/com/oracle/java/testlibrary/JDKToolFinder.java @@ -27,24 +27,43 @@ import java.io.File; public final class JDKToolFinder { - private JDKToolFinder() { - } - - /** - * Returns the full path to an executable in jdk/bin based on System property - * test.jdk (set by jtreg test suite) - * - * @return Full path to an executable in jdk/bin - */ - public static String getJDKTool(String tool) { - String binPath = System.getProperty("test.jdk"); - if (binPath == null) { - throw new RuntimeException("System property 'test.jdk' not set. This property is normally set by jtreg. " - + "When running test separately, set this property using '-Dtest.jdk=/path/to/jdk'."); + private JDKToolFinder() { } - binPath += File.separatorChar + "bin" + File.separatorChar + tool; + /** + * Returns the full path to an executable in jdk/bin based on System + * property {@code compile.jdk} (set by jtreg test suite) + * + * @return Full path to an executable in jdk/bin + */ + public static String getJDKTool(String tool) { + String binPath = System.getProperty("compile.jdk"); + if (binPath == null) { + throw new RuntimeException("System property 'compile.jdk' not set. " + + "This property is normally set by jtreg. " + + "When running test separately, set this property using " + + "'-Dcompile.jdk=/path/to/jdk'."); + } + binPath += File.separatorChar + "bin" + File.separatorChar + tool; - return binPath; - } + return binPath; + } + /** + * Returns the full path to an executable in <current jdk>/bin based + * on System property {@code test.jdk} (set by jtreg test suite) + * + * @return Full path to an executable in jdk/bin + */ + public static String getCurrentJDKTool(String tool) { + String binPath = System.getProperty("test.jdk"); + if (binPath == null) { + throw new RuntimeException("System property 'test.jdk' not set. " + + "This property is normally set by jtreg. " + + "When running test separately, set this property using " + + "'-Dtest.jdk=/path/to/jdk'."); + } + binPath += File.separatorChar + "bin" + File.separatorChar + tool; + + return binPath; + } } diff --git a/hotspot/test/testlibrary/ctw/Makefile b/hotspot/test/testlibrary/ctw/Makefile new file mode 100644 index 00000000000..5bca7754c69 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/Makefile @@ -0,0 +1,73 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +ifneq "x$(ALT_BOOTDIR)" "x" + BOOTDIR := $(ALT_BOOTDIR) +endif + +ifeq "x$(BOOTDIR)" "x" + JDK_HOME := $(shell dirname $(shell which java))/.. +else + JDK_HOME := $(BOOTDIR) +endif + +SRC_DIR = src +BUILD_DIR = build +OUTPUT_DIR = $(BUILD_DIR)/classes +WHITEBOX_DIR = ../whitebox + +JAVAC = $(JDK_HOME)/bin/javac +JAR = $(JDK_HOME)/bin/jar + +SRC_FILES = $(shell find $(SRC_DIR) -name '*.java') + +MAIN_CLASS = sun.hotspot.tools.ctw.CompileTheWorld + +.PHONY: clean cleantmp + +all: ctw.jar cleantmp + +clean: cleantmp + @rm -rf ctw.jar wb.jar + +cleantmp: + @rm -rf filelist manifest.mf + @rm -rf $(BUILD_DIR) + +ctw.jar: filelist wb.jar manifest.mf + @mkdir -p $(OUTPUT_DIR) + $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp wb.jar @filelist + $(JAR) cfm ctw.jar manifest.mf -C $(OUTPUT_DIR) . + +wb.jar: + make -C ${WHITEBOX_DIR} wb.jar + cp ${WHITEBOX_DIR}/wb.jar ./ + make -C ${WHITEBOX_DIR} clean + +filelist: $(SRC_FILES) + @rm -f $@ + @echo $(SRC_FILES) > $@ + +manifest.mf: + @echo "Main-Class: ${MAIN_CLASS}" > manifest.mf diff --git a/hotspot/test/testlibrary/ctw/README b/hotspot/test/testlibrary/ctw/README new file mode 100644 index 00000000000..babb0816229 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/README @@ -0,0 +1,93 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +DESCRIPTION + +This is replacement for CompileTheWorld (CTW) written on java. Its purpose is +to make possible the use of CTW in product builds. + +DEPENDENCES + +The tool depends on Whitebox API. Assumed, that the sources of whitebox are +located in '../whitebox' directory. + +BUILDING + +Simple way to build, just type 'make'. + +Makefile uses environment variables 'ALT_BOOTDIR', 'BOOTDIR' as root-dir of jdk +that will be used for compilation and creating jar. + +On successful building 'ctw.jar' will be created. + +RUNNING + +Since the tool uses WhiteBox API, options 'UnlockDiagnosticVMOptions' and +'WhiteBoxAPI' should be specified, and 'wb.jar' should be added to +boot-classpath: + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar + +Arguments can be paths to '.jar, '.zip', '.lst' files or directories with +classes, that define which classes will be compiled: + - '.jar', '.zip' files and directories are interpreted like in classpath +(including '/*' syntax) + - '.lst' files -- files with class names (in java notation) to compile. +CTW will try to find these classes with default class loader, so they should +be located in classpath. + +Without arguments it would work as old version of CTW: all classes in +boot-classpath will be compiled, excluding classes in 'rt.jar' if 'rt.jar' isn't +first in boot-classpath. + +Due CTW's flags also are not available in product builds, the tool uses +properties with the same names: + - 'CompileTheWorldPreloadClasses' -- type:boolean, default:true, description: +Preload all classes used by a class before start loading + - 'CompileTheWorldStartAt' -- type:long, default:1, description: First class +to consider + - 'CompileTheWorldStopAt' -- type:long, default:Long.MAX_VALUE, description: +Last class to consider + +Also it uses additional properties: + - 'sun.hotspot.tools.ctw.verbose' -- type:boolean, default:false, +description: Verbose output, adds additional information about compilation + - 'sun.hotspot.tools.ctw.logfile' -- type:string, default:null, +description: Path to logfile, if it's null, cout will be used. + +EXAMPLES + +compile classes from 'rt.jar': + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ${JAVA_HOME}/jre/lib/rt.jar + +compile classes from all '.jar' in './testjars' directory: + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./testjars/* + +compile classes from './build/classes' directory: + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar ./build/classes + +compile only java.lang.String, java.lang.Object classes: + $ echo java.lang.String > classes.lst + $ echo java.lang.Object >> classes.lst + $ java -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:wb.jar -jar ctw.jar classes.lst + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java new file mode 100644 index 00000000000..3ee3526568d --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathDirEntry.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Set; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.concurrent.Executor; + +import java.io.*; +import java.nio.file.*; +import java.nio.file.attribute.*; + +/** + * * Handler for dirs containing classes to compile. + * @author igor.ignatyev@oracle.com + */ +public class ClassPathDirEntry extends PathHandler { + + private final int rootLength = root.toString().length(); + + public ClassPathDirEntry(Path root, Executor executor) { + super(root, executor); + try { + URL url = root.toUri().toURL(); + setLoader(new URLClassLoader(new URL[]{url})); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + @Override + public void process() { + System.out.println("# dir: " + root); + if (!Files.exists(root)) { + return; + } + try { + Files.walkFileTree(root, EnumSet.of(FileVisitOption.FOLLOW_LINKS), + Integer.MAX_VALUE, new CompileFileVisitor()); + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + private void processFile(Path file) { + if (Utils.isClassFile(file.toString())) { + processClass(pathToClassName(file)); + } + } + + private String pathToClassName(Path file) { + String fileString; + if (root == file) { + fileString = file.normalize().toString(); + } else { + fileString = file.normalize().toString().substring(rootLength + 1); + } + return Utils.fileNameToClassName(fileString); + } + + private class CompileFileVisitor extends SimpleFileVisitor { + + private final Set ready = new HashSet<>(); + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attrs) throws IOException { + if (ready.contains(dir)) { + return FileVisitResult.SKIP_SUBTREE; + } + ready.add(dir); + return super.preVisitDirectory(dir, attrs); + } + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attrs) throws IOException { + if (!ready.contains(file)) { + processFile(file); + } + return isFinished() ? FileVisitResult.TERMINATE + : FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult visitFileFailed(Path file, + IOException exc) throws IOException { + return FileVisitResult.CONTINUE; + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java new file mode 100644 index 00000000000..3d39f1b2573 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarEntry.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; +import java.util.jar.*; +import java.util.concurrent.Executor; + +import java.io.*; +import java.nio.file.*; + +/** + * Handler for jar-files containing classes to compile. + * @author igor.ignatyev@oracle.com + */ +public class ClassPathJarEntry extends PathHandler { + + public ClassPathJarEntry(Path root, Executor executor) { + super(root, executor); + try { + URL url = root.toUri().toURL(); + setLoader(new URLClassLoader(new URL[]{url})); + } catch (MalformedURLException e) { + e.printStackTrace(); + } + } + + @Override + public void process() { + System.out.println("# jar: " + root); + if (!Files.exists(root)) { + return; + } + try { + JarFile jarFile = new JarFile(root.toFile()); + JarEntry entry; + for (Enumeration e = jarFile.entries(); + e.hasMoreElements(); ) { + entry = e.nextElement(); + processJarEntry(entry); + if (isFinished()) { + return; + } + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } + + private void processJarEntry(JarEntry entry) { + String filename = entry.getName(); + if (Utils.isClassFile(filename)) { + processClass(Utils.fileNameToClassName(filename)); + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java new file mode 100644 index 00000000000..328280a2d88 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassPathJarInDirEntry.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.Executor; + +/** + * Handler for dirs containing jar-files with classes to compile. + * + * @author igor.ignatyev@oracle.com + */ +public class ClassPathJarInDirEntry extends PathHandler { + + public ClassPathJarInDirEntry(Path root, Executor executor) { + super(root, executor); + } + + @Override + public void process() { + System.out.println("# jar_in_dir: " + root); + if (!Files.exists(root)) { + return; + } + try (DirectoryStream ds + = Files.newDirectoryStream(root, "*.jar")) { + for (Path p : ds) { + new ClassPathJarEntry(p, executor).process(); + if (isFinished()) { + return; + } + } + } catch (IOException ioe) { + ioe.printStackTrace(); + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java new file mode 100644 index 00000000000..6f36d8b5c6d --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/ClassesListInFile.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import java.io.BufferedReader; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.concurrent.Executor; + +/** + * Handler for files containing a list of classes to compile. + * + * @author igor.ignatyev@oracle.com + */ +public class ClassesListInFile extends PathHandler { + public ClassesListInFile(Path root, Executor executor) { + super(root, executor); + } + + @Override + public void process() { + System.out.println("# list: " + root); + if (!Files.exists(root)) { + return; + } + try { + try (BufferedReader reader = Files.newBufferedReader(root, + StandardCharsets.UTF_8)) { + String line; + while (!isFinished() && ((line = reader.readLine()) != null)) { + processClass(line); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java new file mode 100644 index 00000000000..f1d46526d31 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/CompileTheWorld.java @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import sun.management.ManagementFactoryHelper; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; + +import java.util.List; +import java.util.concurrent.*; + +/** + * @author igor.ignatyev@oracle.com + */ +public class CompileTheWorld { + /** + * Entry point. Compiles classes in {@code args}, or all classes in + * boot-classpath if args is empty + * + * @param args paths to jar/zip, dir contains classes, or to .lst file + * contains list of classes to compile + */ + public static void main(String[] args) { + String logfile = Utils.LOG_FILE; + PrintStream os = null; + if (logfile != null) { + try { + os = new PrintStream(Files.newOutputStream(Paths.get(logfile))); + } catch (IOException io) { + } + } + if (os != null) { + System.setOut(os); + } + + try { + try { + if (ManagementFactoryHelper.getCompilationMXBean() == null) { + throw new RuntimeException( + "CTW can not work in interpreted mode"); + } + } catch (java.lang.NoClassDefFoundError e) { + // compact1, compact2 support + } + String[] paths = args; + boolean skipRtJar = false; + if (args.length == 0) { + paths = getDefaultPaths(); + skipRtJar = true; + } + ExecutorService executor = createExecutor(); + long start = System.currentTimeMillis(); + try { + String path; + for (int i = 0, n = paths.length; i < n + && !PathHandler.isFinished(); ++i) { + path = paths[i]; + if (skipRtJar && i > 0 && isRtJar(path)) { + // rt.jar is not first, so skip it + continue; + } + PathHandler.create(path, executor).process(); + } + } finally { + await(executor); + } + System.out.printf("Done (%d classes, %d methods, %d ms)%n", + Compiler.getClassCount(), + Compiler.getMethodCount(), + System.currentTimeMillis() - start); + } finally { + if (os != null) { + os.close(); + } + } + } + + private static ExecutorService createExecutor() { + final int threadsCount = Math.min( + Runtime.getRuntime().availableProcessors(), + Utils.CI_COMPILER_COUNT); + ExecutorService result; + if (threadsCount > 1) { + result = new ThreadPoolExecutor(threadsCount, threadsCount, + /* keepAliveTime */ 0L, TimeUnit.MILLISECONDS, + new ArrayBlockingQueue<>(threadsCount), + new ThreadPoolExecutor.CallerRunsPolicy()); + } else { + result = new CurrentThreadExecutor(); + } + return result; + } + + private static String[] getDefaultPaths() { + String property = System.getProperty("sun.boot.class.path"); + System.out.println( + "# use 'sun.boot.class.path' as args: " + property); + return Utils.PATH_SEPARATOR.split(property); + } + + private static void await(ExecutorService executor) { + executor.shutdown(); + while (!executor.isTerminated()) { + try { + executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + break; + } + } + } + + private static boolean isRtJar(String path) { + return Utils.endsWithIgnoreCase(path, File.separator + "rt.jar"); + } + + private static class CurrentThreadExecutor extends AbstractExecutorService { + private boolean isShutdown; + + @Override + public void shutdown() { + this.isShutdown = true; + } + + @Override + public List shutdownNow() { + return null; + } + + @Override + public boolean isShutdown() { + return isShutdown; + } + + @Override + public boolean isTerminated() { + return isShutdown; + } + + @Override + public boolean awaitTermination(long timeout, TimeUnit unit) + throws InterruptedException { + return isShutdown; + } + + @Override + public void execute(Runnable command) { + command.run(); + } + } +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java new file mode 100644 index 00000000000..ccb2d3ae53a --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Compiler.java @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import sun.hotspot.WhiteBox; +import sun.misc.SharedSecrets; +import sun.reflect.ConstantPool; + +import java.lang.reflect.Executable; + +import java.util.Objects; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicLong; + +/** + * Provide method to compile whole class. + * Also contains compiled methods and classes counters. + * + * @author igor.ignatyev@oracle.com + */ +public class Compiler { + private Compiler() { } + private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); + private static final AtomicLong CLASS_COUNT = new AtomicLong(0L); + private static final AtomicLong METHOD_COUNT = new AtomicLong(0L); + private static volatile boolean CLASSES_LIMIT_REACHED = false; + + /** + * @return count of processed classes + */ + public static long getClassCount() { + return CLASS_COUNT.get(); + } + + /** + * @return count of processed methods + */ + public static long getMethodCount() { + return METHOD_COUNT.get(); + } + + /** + * @return {@code true} if classes limit is reached + */ + public static boolean isLimitReached() { + return CLASSES_LIMIT_REACHED; + } + + /** + * Compiles all methods and constructors. + * + * @param aClass class to compile + * @param executor executor used for compile task invocation + * @throws NullPointerException if {@code class} or {@code executor} + * is {@code null} + */ + public static void compileClass(Class aClass, Executor executor) { + Objects.requireNonNull(aClass); + Objects.requireNonNull(executor); + long id = CLASS_COUNT.incrementAndGet(); + if (id > Utils.COMPILE_THE_WORLD_STOP_AT) { + CLASS_COUNT.decrementAndGet(); + CLASSES_LIMIT_REACHED = true; + return; + } + + if (id >= Utils.COMPILE_THE_WORLD_START_AT) { + String name = aClass.getName(); + try { + System.out.printf("[%d]\t%s%n", id, name); + ConstantPool constantPool = SharedSecrets.getJavaLangAccess(). + getConstantPool(aClass); + if (Utils.COMPILE_THE_WORLD_PRELOAD_CLASSES) { + preloadClasses(name, id, constantPool); + } + long methodCount = 0; + for (Executable e : aClass.getDeclaredConstructors()) { + ++methodCount; + executor.execute(new CompileMethodCommand(id, name, e)); + } + for (Executable e : aClass.getDeclaredMethods()) { + ++methodCount; + executor.execute(new CompileMethodCommand(id, name, e)); + } + METHOD_COUNT.addAndGet(methodCount); + + if (Utils.DEOPTIMIZE_ALL_CLASSES_RATE > 0 + && (id % Utils.DEOPTIMIZE_ALL_CLASSES_RATE == 0)) { + WHITE_BOX.deoptimizeAll(); + } + } catch (Throwable t) { + System.out.printf("[%d]\t%s\tskipping %s%n", id, name, t); + t.printStackTrace(); + } + } + } + + private static void preloadClasses(String className, long id, + ConstantPool constantPool) { + try { + for (int i = 0, n = constantPool.getSize(); i < n; ++i) { + try { + constantPool.getClassAt(i); + } catch (IllegalArgumentException ignore) { + } + } + } catch (Throwable t) { + System.out.printf("[%d]\t%s\tpreloading failed : %s%n", id, + className, t); + } + } + + + + /** + * Compilation of method. + * Will compile method on all available comp levels. + */ + private static class CompileMethodCommand implements Runnable { + private final long classId; + private final String className; + private final Executable method; + + /** + * @param classId id of class + * @param className name of class + * @param method compiled for compilation + */ + public CompileMethodCommand(long classId, String className, + Executable method) { + this.classId = classId; + this.className = className; + this.method = method; + } + + @Override + public final void run() { + int compLevel = Utils.INITIAL_COMP_LEVEL; + if (Utils.TIERED_COMPILATION) { + for (int i = compLevel; i <= Utils.TIERED_STOP_AT_LEVEL; ++i) { + WHITE_BOX.deoptimizeMethod(method); + compileMethod(method, i); + } + } else { + compileMethod(method, compLevel); + } + } + + private void waitCompilation() { + if (!Utils.BACKGROUND_COMPILATION) { + return; + } + final Object obj = new Object(); + synchronized (obj) { + for (int i = 0; + i < 10 && WHITE_BOX.isMethodQueuedForCompilation(method); + ++i) { + try { + obj.wait(1000); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + } + } + } + + private void compileMethod(Executable method, int compLevel) { + if (WHITE_BOX.isMethodCompilable(method, compLevel)) { + try { + WHITE_BOX.enqueueMethodForCompilation(method, compLevel); + waitCompilation(); + int tmp = WHITE_BOX.getMethodCompilationLevel(method); + if (tmp != compLevel) { + logMethod(method, "compilation level = " + tmp + + ", but not " + compLevel); + } else if (Utils.IS_VERBOSE) { + logMethod(method, "compilation level = " + tmp + ". OK"); + } + } catch (Throwable t) { + logMethod(method, "error on compile at " + compLevel + + " level"); + t.printStackTrace(); + } + } else if (Utils.IS_VERBOSE) { + logMethod(method, "not compilable at " + compLevel); + } + } + + private void logMethod(Executable method, String message) { + StringBuilder builder = new StringBuilder("["); + builder.append(classId); + builder.append("]\t"); + builder.append(className); + builder.append("::"); + builder.append(method.getName()); + builder.append('('); + Class[] params = method.getParameterTypes(); + for (int i = 0, n = params.length - 1; i < n; ++i) { + builder.append(params[i].getName()); + builder.append(", "); + } + if (params.length != 0) { + builder.append(params[params.length - 1].getName()); + } + builder.append(')'); + if (message != null) { + builder.append('\t'); + builder.append(message); + } + System.err.println(builder); + } + } + +} diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java new file mode 100644 index 00000000000..5c284f896a8 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.io.File; + +import java.util.Objects; +import java.util.regex.Pattern; +import java.util.regex.Matcher; +import java.util.concurrent.Executor; + +/** + * Abstract handler for path. + *

    + * Concrete subclasses should implement method {@link #process()}. + * + * @author igor.ignatyev@oracle.com + */ +public abstract class PathHandler { + private static final Pattern JAR_IN_DIR_PATTERN + = Pattern.compile("^(.*[/\\\\])?\\*$"); + protected final Path root; + protected final Executor executor; + private ClassLoader loader; + + /** + * @param root root path to process + * @param executor executor used for process task invocation + * @throws NullPointerException if {@code root} or {@code executor} is + * {@code null} + */ + protected PathHandler(Path root, Executor executor) { + Objects.requireNonNull(root); + Objects.requireNonNull(executor); + this.root = root.normalize(); + this.executor = executor; + this.loader = ClassLoader.getSystemClassLoader(); + } + + /** + * Factory method. Construct concrete handler in depends from {@code path}. + * + * @param path the path to process + * @param executor executor used for compile task invocation + * @throws NullPointerException if {@code path} or {@code executor} is + * {@code null} + */ + public static PathHandler create(String path, Executor executor) { + Objects.requireNonNull(path); + Objects.requireNonNull(executor); + Matcher matcher = JAR_IN_DIR_PATTERN.matcher(path); + if (matcher.matches()) { + path = matcher.group(1); + path = path.isEmpty() ? "." : path; + return new ClassPathJarInDirEntry(Paths.get(path), executor); + } else { + path = path.isEmpty() ? "." : path; + Path p = Paths.get(path); + if (isJarFile(p)) { + return new ClassPathJarEntry(p, executor); + } else if (isListFile(p)) { + return new ClassesListInFile(p, executor); + } else { + return new ClassPathDirEntry(p, executor); + } + } + } + + private static boolean isJarFile(Path path) { + if (Files.isRegularFile(path)) { + String name = path.toString(); + return Utils.endsWithIgnoreCase(name, ".zip") + || Utils.endsWithIgnoreCase(name, ".jar"); + } + return false; + } + + private static boolean isListFile(Path path) { + if (Files.isRegularFile(path)) { + String name = path.toString(); + return Utils.endsWithIgnoreCase(name, ".lst"); + } + return false; + } + + /** + * Processes all classes in specified path. + */ + public abstract void process(); + + /** + * Sets class loader, that will be used to define class at + * {@link #processClass(String)}. + * + * @param loader class loader + * @throws NullPointerException if {@code loader} is {@code null} + */ + protected final void setLoader(ClassLoader loader) { + Objects.requireNonNull(loader); + this.loader = loader; + } + + /** + * Processes specificed class. + * @param name fully qualified name of class to process + */ + protected final void processClass(String name) { + try { + Class aClass = Class.forName(name, true, loader); + Compiler.compileClass(aClass, executor); + } catch (ClassNotFoundException | LinkageError e) { + System.out.printf("Class %s loading failed : %s%n", name, + e.getMessage()); + } + } + + /** + * @return {@code true} if processing should be stopped + */ + public static boolean isFinished() { + return Compiler.isLimitReached(); + } + +} + diff --git a/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java new file mode 100644 index 00000000000..5ffd06cee8b --- /dev/null +++ b/hotspot/test/testlibrary/ctw/src/sun/hotspot/tools/ctw/Utils.java @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.hotspot.tools.ctw; + +import com.sun.management.HotSpotDiagnosticMXBean; +import sun.management.ManagementFactoryHelper; + +import java.io.File; +import java.util.regex.Pattern; + +/** + * Auxiliary methods. + * + * @author igor.ignatyev@oracle.com + */ +public class Utils { + /** + * Value of {@code -XX:CompileThreshold} + */ + public static final boolean TIERED_COMPILATION + = Boolean.parseBoolean(getVMOption("TieredCompilation", "false")); + /** + * Value of {@code -XX:BackgroundCompilation} + */ + public static final boolean BACKGROUND_COMPILATION + = Boolean.parseBoolean(getVMOption("BackgroundCompilation", + "false")); + /** + * Value of {@code -XX:TieredStopAtLevel} + */ + public static final int TIERED_STOP_AT_LEVEL; + /** + * Value of {@code -XX:CICompilerCount} + */ + public static final Integer CI_COMPILER_COUNT + = Integer.valueOf(getVMOption("CICompilerCount", "1")); + /** + * Initial compilation level. + */ + public static final int INITIAL_COMP_LEVEL; + /** + * Compiled path-separator regexp. + */ + public static final Pattern PATH_SEPARATOR = Pattern.compile( + File.pathSeparator, Pattern.LITERAL); + /** + * Value of {@code -DDeoptimizeAllClassesRate}. Frequency of + * {@code WB.deoptimizeAll()} invocation If it less that {@code 0}, + * {@code WB.deoptimizeAll()} will not be invoked. + */ + public static final int DEOPTIMIZE_ALL_CLASSES_RATE + = Integer.getInteger("DeoptimizeAllClassesRate", -1); + /** + * Value of {@code -DCompileTheWorldStopAt}. Last class to consider. + */ + public static final long COMPILE_THE_WORLD_STOP_AT + = Long.getLong("CompileTheWorldStopAt", Long.MAX_VALUE); + /** + * Value of {@code -DCompileTheWorldStartAt}. First class to consider. + */ + public static final long COMPILE_THE_WORLD_START_AT + = Long.getLong("CompileTheWorldStartAt", 1); + /** + * Value of {@code -DCompileTheWorldPreloadClasses}. Preload all classes + * used by a class before start loading. + */ + public static final boolean COMPILE_THE_WORLD_PRELOAD_CLASSES; + /** + * Value of {@code -Dsun.hotspot.tools.ctw.verbose}. Verbose output, + * adds additional information about compilation. + */ + public static final boolean IS_VERBOSE + = Boolean.getBoolean("sun.hotspot.tools.ctw.verbose"); + /** + * Value of {@code -Dsun.hotspot.tools.ctw.logfile}.Path to logfile, if + * it's null, cout will be used. + */ + public static final String LOG_FILE + = System.getProperty("sun.hotspot.tools.ctw.logfile"); + static { + if (Utils.TIERED_COMPILATION) { + INITIAL_COMP_LEVEL = 1; + } else { + String vmName = System.getProperty("java.vm.name"); + if (Utils.endsWithIgnoreCase(vmName, " Server VM")) { + INITIAL_COMP_LEVEL = 4; + } else if (Utils.endsWithIgnoreCase(vmName, " Client VM") + || Utils.endsWithIgnoreCase(vmName, " Minimal VM")) { + INITIAL_COMP_LEVEL = 1; + } else { + throw new RuntimeException("Unknown VM: " + vmName); + } + } + + TIERED_STOP_AT_LEVEL = Integer.parseInt(getVMOption("TieredStopAtLevel", + String.valueOf(INITIAL_COMP_LEVEL))); + } + + static { + String tmp = System.getProperty("CompileTheWorldPreloadClasses"); + if (tmp == null) { + COMPILE_THE_WORLD_PRELOAD_CLASSES = true; + } else { + COMPILE_THE_WORLD_PRELOAD_CLASSES = Boolean.parseBoolean(tmp); + } + } + + public static final String CLASSFILE_EXT = ".class"; + + private Utils() { + } + + /** + * Tests if the string ends with the suffix, ignoring case + * considerations + * + * @param string the tested string + * @param suffix the suffix + * @return {@code true} if {@code string} ends with the {@code suffix} + * @see String#endsWith(String) + */ + public static boolean endsWithIgnoreCase(String string, String suffix) { + if (string == null || suffix == null) { + return false; + } + int length = suffix.length(); + int toffset = string.length() - length; + if (toffset < 0) { + return false; + } + return string.regionMatches(true, toffset, suffix, 0, length); + } + + /** + * Returns value of VM option. + * + * @param name option's name + * @return value of option or {@code null}, if option doesn't exist + * @throws NullPointerException if name is null + */ + public static String getVMOption(String name) { + String result; + HotSpotDiagnosticMXBean diagnostic + = ManagementFactoryHelper.getDiagnosticMXBean(); + result = diagnostic.getVMOption(name).getValue(); + return result; + } + + /** + * Returns value of VM option or default value. + * + * @param name option's name + * @param defaultValue default value + * @return value of option or {@code defaultValue}, if option doesn't exist + * @throws NullPointerException if name is null + * @see #getVMOption(String) + */ + public static String getVMOption(String name, String defaultValue) { + String result; + try { + result = getVMOption(name); + } catch (NoClassDefFoundError e) { + // compact1, compact2 support + result = defaultValue; + } + return result == null ? defaultValue : result; + } + + /** + * Tests if the filename is valid filename for class file. + * + * @param filename tested filename + */ + public static boolean isClassFile(String filename) { + // If the filename has a period after removing '.class', it's not valid class file + return endsWithIgnoreCase(filename, CLASSFILE_EXT) + && (filename.indexOf('.') + == (filename.length() - CLASSFILE_EXT.length())); + } + + /** + * Converts the filename to classname. + * + * @param filename filename to convert + * @return corresponding classname. + * @throws AssertionError if filename isn't valid filename for class file - + * {@link #isClassFile(String)} + */ + public static String fileNameToClassName(String filename) { + assert isClassFile(filename); + return filename.substring(0, filename.length() - CLASSFILE_EXT.length()) + .replace(File.separatorChar, '.'); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/Bar.java b/hotspot/test/testlibrary/ctw/test/Bar.java new file mode 100644 index 00000000000..9b0324555f8 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/Bar.java @@ -0,0 +1,5 @@ +public class Bar { + private static void staticMethod() { } + public void method() { } + protected Bar() { } +} diff --git a/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java new file mode 100644 index 00000000000..ae5eaf0f2e4 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/ClassesDirTest.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test ClassesDirTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesDirTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main ClassesDirTest prepare + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes + * @run main ClassesDirTest check ctw.log + * @summary testing of CompileTheWorld :: classes in directory + * @author igor.ignatyev@oracle.com + */ + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +public class ClassesDirTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# dir: classes", "Done (2 classes, 6 methods, "}; + + private ClassesDirTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new ClassesDirTest().run(args); + } + + protected void prepare() throws Exception { + String path = "classes"; + Files.createDirectory(Paths.get(path)); + Files.move(Paths.get("Foo.class"), Paths.get(path, "Foo.class"), + StandardCopyOption.REPLACE_EXISTING); + Files.move(Paths.get("Bar.class"), Paths.get(path, "Bar.class"), + StandardCopyOption.REPLACE_EXISTING); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/ClassesListTest.java b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java new file mode 100644 index 00000000000..a98cd53a3f6 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/ClassesListTest.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test ClassesListTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox ClassesListTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main ClassesListTest prepare + * @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld classes.lst + * @run main ClassesListTest check ctw.log + * @summary testing of CompileTheWorld :: list of classes in file + * @author igor.ignatyev@oracle.com + */ + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; + +public class ClassesListTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# list: classes.lst", "Done (4 classes, "}; + + private ClassesListTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new ClassesListTest().run(args); + } + + protected void prepare() throws Exception { + String path = "classes.lst"; + Files.copy(Paths.get(System.getProperty("test.src"), path), + Paths.get(path), StandardCopyOption.REPLACE_EXISTING); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/CtwTest.java b/hotspot/test/testlibrary/ctw/test/CtwTest.java new file mode 100644 index 00000000000..ecc9c59c13a --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/CtwTest.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.util.List; +import java.util.Collections; +import java.util.ArrayList; + +import java.io.File; +import java.io.Writer; +import java.io.FileWriter; +import java.io.IOException; +import java.io.BufferedReader; + +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.nio.charset.Charset; + +import com.oracle.java.testlibrary.JDKToolFinder; +import com.oracle.java.testlibrary.OutputAnalyzer; + +public abstract class CtwTest { + protected final String[] shouldContain; + protected CtwTest(String[] shouldContain) { + this.shouldContain = shouldContain; + } + + public void run(String[] args) throws Exception { + if (args.length == 0) { + throw new Error("args is empty"); + } + switch (args[0]) { + case "prepare": + prepare(); + break; + case "check": + check(args); + break; + default: + throw new Error("unregonized action -- " + args[0]); + } + } + + protected void prepare() throws Exception { } + + protected void check(String[] args) throws Exception { + if (args.length < 2) { + throw new Error("logfile isn't specified"); + } + String logfile = args[1]; + try (BufferedReader r = Files.newBufferedReader(Paths.get(logfile), + Charset.defaultCharset())) { + OutputAnalyzer output = readOutput(r); + for (String test : shouldContain) { + output.shouldContain(test); + } + } + } + + private static OutputAnalyzer readOutput(BufferedReader reader) + throws IOException { + StringBuilder builder = new StringBuilder(); + String eol = String.format("%n"); + String line; + + while ((line = reader.readLine()) != null) { + builder.append(line); + builder.append(eol); + } + return new OutputAnalyzer(builder.toString(), ""); + } + + protected void dump(OutputAnalyzer output, String name) { + try (Writer w = new FileWriter(name + ".out")) { + String s = output.getStdout(); + w.write(s, s.length(), 0); + } catch (IOException io) { + io.printStackTrace(); + } + try (Writer w = new FileWriter(name + ".err")) { + String s = output.getStderr(); + w.write(s, s.length(), 0); + } catch (IOException io) { + io.printStackTrace(); + } + } + + protected ProcessBuilder createJarProcessBuilder(String... command) + throws Exception { + String javapath = JDKToolFinder.getJDKTool("jar"); + + ArrayList args = new ArrayList<>(); + args.add(javapath); + Collections.addAll(args, command); + + return new ProcessBuilder(args.toArray(new String[args.size()])); + } +} diff --git a/hotspot/test/testlibrary/ctw/test/Foo.java b/hotspot/test/testlibrary/ctw/test/Foo.java new file mode 100644 index 00000000000..07d8f4643ce --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/Foo.java @@ -0,0 +1,5 @@ +public class Foo { + private static void staticMethod() { } + public void method() { } + protected Foo() { } +} diff --git a/hotspot/test/testlibrary/ctw/test/JarDirTest.java b/hotspot/test/testlibrary/ctw/test/JarDirTest.java new file mode 100644 index 00000000000..76f682fd755 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/JarDirTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test JarDirTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarDirTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main JarDirTest prepare + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld jars/* + * @run main JarDirTest check ctw.log + * @summary testing of CompileTheWorld :: jars in directory + * @author igor.ignatyev@oracle.com + */ + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class JarDirTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# jar_in_dir: jars", + "# jar: jars" + File.separator +"foo.jar", + "# jar: jars" + File.separator +"bar.jar", + "Done (4 classes, 12 methods, "}; + + private JarDirTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new JarDirTest().run(args); + } + + protected void prepare() throws Exception { + String path = "jars"; + Files.createDirectory(Paths.get(path)); + + ProcessBuilder pb = createJarProcessBuilder("cf", "jars/foo.jar", + "Foo.class", "Bar.class"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-foo.jar"); + output.shouldHaveExitValue(0); + + pb = createJarProcessBuilder("cf", "jars/bar.jar", "Foo.class", + "Bar.class"); + output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-bar.jar"); + output.shouldHaveExitValue(0); + } + +} diff --git a/hotspot/test/testlibrary/ctw/test/JarsTest.java b/hotspot/test/testlibrary/ctw/test/JarsTest.java new file mode 100644 index 00000000000..04792729f4e --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/JarsTest.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test JarsTest + * @bug 8012447 + * @library /testlibrary /testlibrary/whitebox /testlibrary/ctw/src + * @build sun.hotspot.tools.ctw.CompileTheWorld sun.hotspot.WhiteBox JarsTest Foo Bar + * @run main ClassFileInstaller sun.hotspot.WhiteBox Foo Bar + * @run main JarsTest prepare + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Dsun.hotspot.tools.ctw.logfile=ctw.log sun.hotspot.tools.ctw.CompileTheWorld foo.jar bar.jar + * @run main JarsTest check ctw.log + * @summary testing of CompileTheWorld :: jars + * @author igor.ignatyev@oracle.com + */ + +import com.oracle.java.testlibrary.OutputAnalyzer; + +public class JarsTest extends CtwTest { + private static final String[] SHOULD_CONTAIN + = {"# jar: foo.jar", "# jar: bar.jar", + "Done (4 classes, 12 methods, "}; + + private JarsTest() { + super(SHOULD_CONTAIN); + } + + public static void main(String[] args) throws Exception { + new JarsTest().run(args); + } + + protected void prepare() throws Exception { + ProcessBuilder pb = createJarProcessBuilder("cf", "foo.jar", + "Foo.class", "Bar.class"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-foo.jar"); + output.shouldHaveExitValue(0); + + pb = createJarProcessBuilder("cf", "bar.jar", "Foo.class", "Bar.class"); + output = new OutputAnalyzer(pb.start()); + dump(output, "ctw-bar.jar"); + output.shouldHaveExitValue(0); + } + +} diff --git a/hotspot/test/testlibrary/ctw/test/classes.lst b/hotspot/test/testlibrary/ctw/test/classes.lst new file mode 100644 index 00000000000..044c029e783 --- /dev/null +++ b/hotspot/test/testlibrary/ctw/test/classes.lst @@ -0,0 +1,4 @@ +java.lang.String +java.lang.Object +Foo +Bar diff --git a/hotspot/test/testlibrary/whitebox/Makefile b/hotspot/test/testlibrary/whitebox/Makefile new file mode 100644 index 00000000000..8a84a0a4492 --- /dev/null +++ b/hotspot/test/testlibrary/whitebox/Makefile @@ -0,0 +1,63 @@ +# +# Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# + +ifneq "x$(ALT_BOOTDIR)" "x" + BOOTDIR := $(ALT_BOOTDIR) +endif + +ifeq "x$(BOOTDIR)" "x" + JDK_HOME := $(shell dirname $(shell which java))/.. +else + JDK_HOME := $(BOOTDIR) +endif + +SRC_DIR = ./ +BUILD_DIR = build +OUTPUT_DIR = $(BUILD_DIR)/classes + +JAVAC = $(JDK_HOME)/bin/javac +JAR = $(JDK_HOME)/bin/jar + +SRC_FILES = $(shell find $(SRC_DIR) -name '*.java') + +.PHONY: filelist clean cleantmp + +all: wb.jar cleantmp + +wb.jar: filelist + @mkdir -p $(OUTPUT_DIR) + $(JAVAC) -sourcepath $(SRC_DIR) -d $(OUTPUT_DIR) -cp $(OUTPUT_DIR) @filelist + $(JAR) cf wb.jar -C $(OUTPUT_DIR) . + @rm -rf $(OUTPUT_DIR) + +filelist: $(SRC_FILES) + @rm -f $@ + @echo $(SRC_FILES) > $@ + +clean: cleantmp + @rm -rf wb.jar + +cleantmp: + @rm -rf filelist + @rm -rf $(BUILD_DIR) diff --git a/jdk/.hgtags b/jdk/.hgtags index c20c5cde8f0..3e3a625970b 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -228,3 +228,4 @@ e0f6039c0290b7381042a6fec3100a69a5a67e37 jdk8-b103 f1d8d15bfcb5ada858a942f8a31f6598f23214d1 jdk8-b104 1fe211ae3d2b8cc2dfc4f58d9a6eb96418679672 jdk8-b105 c817276bd870dfe1dcc3a3dbbc092436b6907f75 jdk8-b106 +eea685b9ccaa1980e0a7e07d6a3a84bcc7e9ab82 jdk8-b107 diff --git a/jdk/make/Makefile b/jdk/make/Makefile index c2db5a816a2..e82edd7271f 100644 --- a/jdk/make/Makefile +++ b/jdk/make/Makefile @@ -99,7 +99,6 @@ COMPILER_PATH.desc = Compiler install directory CACERTS_FILE.desc = Location of certificates file DEVTOOLS_PATH.desc = Directory containing zip and unzip CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files -DXSDK_PATH.desc = Root directory of DirectX SDK # Make variables to print out (description and value) VARIABLE_PRINTVAL_LIST += \ @@ -128,17 +127,6 @@ VARIABLE_CHECKDIR_LIST += \ VARIABLE_CHECKFIL_LIST += \ CACERTS_FILE -# Some are windows specific -ifeq ($(PLATFORM), windows) - -VARIABLE_PRINTVAL_LIST += \ - DXSDK_PATH - -VARIABLE_CHECKDIR_LIST += \ - DXSDK_PATH - -endif - # For pattern rules below, so all are treated the same DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval) DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir) diff --git a/jdk/make/common/Defs-macosx.gmk b/jdk/make/common/Defs-macosx.gmk index 1b7aaa8ae20..befd2cfed5b 100644 --- a/jdk/make/common/Defs-macosx.gmk +++ b/jdk/make/common/Defs-macosx.gmk @@ -397,12 +397,10 @@ else INCLUDE_SA = true endif -ifdef CROSS_COMPILE_ARCH - # X11 headers are not under /usr/include - OTHER_CFLAGS += -I$(OPENWIN_HOME)/include - OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include - OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include -endif +# X11 headers are not under /usr/include +OTHER_CFLAGS += -I$(OPENWIN_HOME)/include +OTHER_CXXFLAGS += -I$(OPENWIN_HOME)/include +OTHER_CPPFLAGS += -I$(OPENWIN_HOME)/include LIB_LOCATION ?= $(LIBDIR) diff --git a/jdk/make/common/Defs-windows.gmk b/jdk/make/common/Defs-windows.gmk index c5c15b3d387..ef2c4aeab6f 100644 --- a/jdk/make/common/Defs-windows.gmk +++ b/jdk/make/common/Defs-windows.gmk @@ -78,8 +78,6 @@ ifeq ($(COMPILER_VERSION), VS2010) MS_RUNTIME_LIBRARIES = $(MSVCRNN_DLL) endif -EXTRA_LFLAGS += -LIBPATH:$(DXSDK_LIB_PATH) - # Full Debug Symbols has been enabled on Windows since JDK1.4.1. # The Full Debug Symbols (FDS) default for VARIANT == OPT builds is # enabled with debug info files ZIP'ed to save space. For VARIANT != diff --git a/jdk/make/common/Sanity.gmk b/jdk/make/common/Sanity.gmk index 25f5fa7bfe8..233abeacabb 100644 --- a/jdk/make/common/Sanity.gmk +++ b/jdk/make/common/Sanity.gmk @@ -65,7 +65,6 @@ sanity-base: pre-sanity \ sane-libCrun \ sane-unixccs_path \ sane-msdevtools_path \ - sane-dxsdk \ sane-compiler \ sane-cacerts \ sane-ant_version \ diff --git a/jdk/make/common/shared/Defs-versions.gmk b/jdk/make/common/shared/Defs-versions.gmk index 8a60563c122..a3a53c5c048 100644 --- a/jdk/make/common/shared/Defs-versions.gmk +++ b/jdk/make/common/shared/Defs-versions.gmk @@ -74,9 +74,6 @@ endif # REQUIRED_CYGWIN_VER # Windows only: If CYGWIN is used, the minimum CYGWIN version. # -# REQUIRED_DXSDK_VER -# Windows only: The version of DirectX SDK expected. -# # REQUIRED_FREETYPE_VERSION # If we are using freetype, the freetype version expected. # @@ -193,7 +190,6 @@ ifeq ($(PLATFORM), windows) REQUIRED_OS_VARIANT_VERSION = $(REQUIRED_OS_VERSION) REQUIRED_CYGWIN_VER = 4.0 REQUIRED_MKS_VER = 6.1 - REQUIRED_DXSDK_VER = 0x0900 ifeq ($(CC_VERSION),msvc) REQUIRED_COMPILER_NAME = Visual Studio 10 REQUIRED_COMPILER_VERSION = VS2010 diff --git a/jdk/make/common/shared/Defs-windows.gmk b/jdk/make/common/shared/Defs-windows.gmk index 40415547d71..d46d884cc05 100644 --- a/jdk/make/common/shared/Defs-windows.gmk +++ b/jdk/make/common/shared/Defs-windows.gmk @@ -79,7 +79,7 @@ override INCREMENTAL_BUILD = false # The ALT values should never really have spaces or use \. # Suspect these environment variables to have spaces and/or \ characters: # SYSTEMROOT, SystemRoot, WINDIR, windir, PROGRAMFILES, ProgramFiles, -# DXSDK_DIR, MSTOOLS, Mstools, MSSDK, MSSdk, VCnnCOMNTOOLS, +# MSTOOLS, Mstools, MSSDK, MSSdk, VCnnCOMNTOOLS, # MSVCDIR, MSVCDir. # So use $(subst \,/,) on them first adding quotes and placing them in # their own variable assigned with :=, then use FullPath. @@ -255,18 +255,6 @@ ifneq ($(word 1,$(_program_files)),$(_program_files)) _program_files:= endif -# DirectX SDK -ifdef ALT_DXSDK_DRIVE - _dx_sdk_dir =$(ALT_DXSDK_DRIVE):/DXSDK -else - ifdef DXSDK_DIR - xDXSDK_DIR :="$(subst \,/,$(DXSDK_DIR))" - else - xDXSDK_DIR :="$(_system_drive)/DXSDK" - endif - _dx_sdk_dir :=$(call FullPath,$(xDXSDK_DIR)) -endif - # Use of the Visual Studio compilers requires certain env variables be set: # PATH should include the path to cl.exe # INCLUDE should be defined @@ -489,39 +477,6 @@ ifeq ($(_NEEDS_MSVCRNN), true) MSVCRNN_DLL_PATH:=$(call AltCheckValue,MSVCRNN_DLL_PATH) endif -# DXSDK_PATH: path to Microsoft DirectX SDK Include and Lib -ifdef ALT_DXSDK_PATH - xALT_DXSDK_PATH :="$(subst \,/,$(ALT_DXSDK_PATH))" - DXSDK_PATH :=$(call FullPath,$(xALT_DXSDK_PATH)) -else - _DXSDK_PATH1 :=$(_dx_sdk_dir) - _DXSDK_PATH2 :=$(JDK_DEVTOOLS_DIR)/windows/dxsdk - DXSDK_PATH :=$(call DirExists,$(_DXSDK_PATH1),$(_DXSDK_PATH2),$(_dx_sdk_dir)) -endif -DXSDK_PATH :=$(call AltCheckSpaces,DXSDK_PATH) -DXSDK_PATH:=$(call AltCheckValue,DXSDK_PATH) - -# DXSDK_INCLUDE_PATH: path to Microsoft DirectX SDK Include -ifdef ALT_DXSDK_INCLUDE_PATH - xALT_DXSDK_INCLUDE_PATH :="$(subst \,/,$(ALT_DXSDK_INCLUDE_PATH))" - DXSDK_INCLUDE_PATH :=$(call FullPath,$(xALT_DXSDK_INCLUDE_PATH)) -else - DXSDK_INCLUDE_PATH =$(subst //,/,$(DXSDK_PATH)/Include) -endif - -# DXSDK_LIB_PATH: path to Microsoft DirectX SDK Lib -ifdef ALT_DXSDK_LIB_PATH - xALT_DXSDK_LIB_PATH :="$(subst \,/,$(ALT_DXSDK_LIB_PATH))" - DXSDK_LIB_PATH :=$(call FullPath,$(xALT_DXSDK_LIB_PATH)) -else - ifeq ($(ARCH_DATA_MODEL), 64) - # 64bit libs are located in "Lib/x64" subdir - DXSDK_LIB_PATH =$(subst //,/,$(DXSDK_PATH)/Lib/x64) - else - DXSDK_LIB_PATH =$(subst //,/,$(DXSDK_PATH)/Lib) - endif -endif - # DEPLOY_MSSDK: Microsoft SDK for this platform (for deploy) ifdef ALT_DEPLOY_MSSDK xALT_DEPLOY_MSSDK :="$(subst \,/,$(ALT_DEPLOY_MSSDK))" diff --git a/jdk/make/common/shared/Sanity-Settings.gmk b/jdk/make/common/shared/Sanity-Settings.gmk index ea32eeadcaa..2ceef21e13e 100644 --- a/jdk/make/common/shared/Sanity-Settings.gmk +++ b/jdk/make/common/shared/Sanity-Settings.gmk @@ -234,10 +234,6 @@ endif ALL_SETTINGS+=$(call addAltSetting,HOTSPOT_SERVER_PATH) ifeq ($(PLATFORM),windows) ALL_SETTINGS+=$(call addAltSetting,HOTSPOT_LIB_PATH) - ALL_SETTINGS+=$(call addRequiredSetting,DXSDK_VER) - ALL_SETTINGS+=$(call addAltSetting,DXSDK_PATH) - ALL_SETTINGS+=$(call addAltSetting,DXSDK_INCLUDE_PATH) - ALL_SETTINGS+=$(call addAltSetting,DXSDK_LIB_PATH) ALL_SETTINGS+=$(call addAltSetting,WINDOWSSDKDIR) ALL_SETTINGS+=$(call addRequiredSetting,RC) ALL_SETTINGS+=$(call addRequiredSetting,REBASE) diff --git a/jdk/make/common/shared/Sanity.gmk b/jdk/make/common/shared/Sanity.gmk index c4a96d73c5f..a9f4692064a 100644 --- a/jdk/make/common/shared/Sanity.gmk +++ b/jdk/make/common/shared/Sanity.gmk @@ -143,8 +143,6 @@ ifeq ($(PLATFORM), windows) _CYGWIN_VER := $(SYSTEM_UNAME) CYGWIN_VER :=$(call GetVersion,$(_CYGWIN_VER)) endif - DXSDK_VER := $(shell $(EGREP) DIRECT3D_VERSION $(DXSDK_INCLUDE_PATH)/d3d9.h 2>&1 | \ - $(EGREP) "\#define" | $(NAWK) '{print $$3}') endif # Get the version numbers of what we are using @@ -1300,51 +1298,6 @@ sane-unzip_version: "" >> $(WARNING_FILE) ; \ fi -###################################################### -# Check for windows DirectX sdk directory -###################################################### -sane-dxsdk: -ifeq ($(PLATFORM), windows) - @if [ ! -r $(DXSDK_INCLUDE_PATH)/d3d9.h ]; then \ - $(ECHO) "ERROR: You do not have access to a valid DirectX SDK Include dir.\n" \ - " The value of DXSDK_INCLUDE_PATH must point a valid DX SDK dir.\n" \ - " Please check your access to \n" \ - " $(DXSDK_INCLUDE_PATH) \n" \ - " and/or check your value of ALT_DXSDK_PATH or ALT_DXSDK_INCLUDE_PATH.\n" \ - " Microsoft DirectX 9 SDK (Summer 2004 Update or newer) can be downloaded from the following location:\n" \ - " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \ - " Or http://www.microsoft.com/directx\n" \ - "" >> $(ERROR_FILE) ; \ - else \ - if [ ! "$(DXSDK_VER)" = "$(REQUIRED_DXSDK_VER)" ]; then \ - $(ECHO) "ERROR: The DirectX SDK must be version $(REQUIRED_DXSDK_VER).\n" \ - " $(YOU_ARE_USING) DirectX SDK version: $(DXSDK_VER)\n" \ - " The DirectX SDK was obtained from the following location: \n" \ - " $(DXSDK_PATH) \n" \ - " Please change your DirectX SDK. \n" \ - " Microsoft DirectX 9 SDK (Summer 2004 Update or newer) can be downloaded from the following location:\n" \ - " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \ - " Or http://www.microsoft.com/directx\n" \ - "" >> $(ERROR_FILE) ; \ - else \ - if [ -r $(DXSDK_INCLUDE_PATH)/basetsd.h ]; then \ - if [ `$(EGREP) -c __int3264 $(DXSDK_INCLUDE_PATH)/basetsd.h` -ne 0 ]; then \ - $(ECHO) "WARNING: The DirectX SDK Include directory contains a newer basetsd.h,\n" \ - " which may indicate that you're using an incorrect version of DirectX SDK.\n" \ - " This may result in a build failure.\n" \ - " The DirectX SDK Include dir was obtained from the following location:\n" \ - " $(DXSDK_INCLUDE_PATH) \n" \ - " Please change your DirectX SDK to version 9 (Summer 2004 Update or newer).\n" \ - " Microsoft DirectX 9 SDK can be downloaded from the following location:\n" \ - " http://msdn.microsoft.com/library/default.asp?url=/downloads/list/directx.asp\n" \ - " Or http://www.microsoft.com/directx\n" \ - "" >> $(WARNING_FILE) ; \ - fi \ - fi \ - fi \ - fi -endif - ###################################################### # Check the linker version(s) ###################################################### diff --git a/jdk/make/java/java/Makefile b/jdk/make/java/java/Makefile index 829cf933001..d2a663f9ae0 100644 --- a/jdk/make/java/java/Makefile +++ b/jdk/make/java/java/Makefile @@ -105,6 +105,7 @@ FILES_java += java/util/prefs/MacOSXPreferences.java \ java/util/prefs/MacOSXPreferencesFactory.java CFLAGS_$(VARIANT)/java_props_md.o = -Os -x objective-c +CFLAGS_$(VARIANT)/java_props_macosx.o = -Os -x objective-c endif # diff --git a/jdk/make/java/java/genlocales.gmk b/jdk/make/java/java/genlocales.gmk index 6d35b8e734d..0d52565c9c5 100644 --- a/jdk/make/java/java/genlocales.gmk +++ b/jdk/make/java/java/genlocales.gmk @@ -38,31 +38,31 @@ FILES_compiled_properties_orig := $(FILES_compiled_properties) # only FILES_java and FILES_compiled_properties variables will be picked up # # $(BUILDDIR)/java/util/FILES_java.gmk & $(BUILDDIR)/java/util/FILES_properties.gmk -# contain "sun.util.resources" for US language support +# contain "sun.util.resources" for EN language support include $(BUILDDIR)/java/util/FILES_java.gmk include $(BUILDDIR)/java/util/FILES_properties.gmk -US_Resources_java := $(FILES_java) -US_Resources_properties := $(FILES_compiled_properties) +EN_Resources_java := $(FILES_java) +EN_Resources_properties := $(FILES_compiled_properties) # $(BUILDDIR)/java/text/FILES_java.gmk contains the "sun.text.resources" for -# US language support +# EN language support include $(BUILDDIR)/java/text/base/FILES_java.gmk -US_Resources_java += $(FILES_java) +EN_Resources_java += $(FILES_java) FILES_compiled_properties= # $(BUILDDIR)/sun/text/FILES_java.gmk & $(BUILDDIR)/sun/text/FILES_properties.gmk -# contain both resources for Non-US language support +# contain both resources for Non-EN language support include $(BUILDDIR)/sun/text/FILES_java.gmk include $(BUILDDIR)/sun/text/FILES_properties.gmk -NonUS_Resources_java := $(FILES_java) -NonUS_Resources_properties := $(FILES_compiled_properties) +NonEN_Resources_java := $(FILES_java) +NonEN_Resources_properties := $(FILES_compiled_properties) # Restore the orignal FILES_java & FILES_compiled_properties variables FILES_java := $(FILES_java_orig) @@ -80,30 +80,30 @@ RESOURCE_NAMES="FormatData CollationData TimeZoneNames LocaleNames CurrencyNames ifeq ($(PLATFORM), macosx) $(LocaleDataMetaInfo_Dest):$(LocaleDataMetaInfo_Src) $(LOCALEGEN_SH) - @$(RM) $@.tmp.us $@.tmp.nonus; + @$(RM) $@.tmp.en $@.tmp.nonen; @$(prep-target) - @$(ECHO) $(US_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.us; - @$(ECHO) $(US_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.us; - @$(ECHO) $(NonUS_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.nonus; - @$(ECHO) $(NonUS_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.nonus; + @$(ECHO) $(EN_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.en; + @$(ECHO) $(EN_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.en; + @$(ECHO) $(NonEN_Resources_properties) | $(NAWK) 'gsub(/.properties/,"\n") {print}' > $@.tmp.nonen; + @$(ECHO) $(NonEN_Resources_java) | $(NAWK) 'gsub(/.java/,"\n") {print}' >> $@.tmp.nonen; NAWK="$(NAWK)" SED="$(SED)" SORT="$(SORT)" \ - $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.us \ - $@.tmp.nonus $< $@ - @$(RM) $@.tmp.us $@.tmp.nonus; + $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.en \ + $@.tmp.nonen $< $@ + @$(RM) $@.tmp.en $@.tmp.nonen; else $(LocaleDataMetaInfo_Dest):$(LocaleDataMetaInfo_Src) $(LOCALEGEN_SH) - @$(RM) $@.tmp.us $@.tmp.nonus; + @$(RM) $@.tmp.en $@.tmp.nonen; @$(prep-target) - @$(ECHO) $(subst .properties,'\n',$(US_Resources_properties)) > $@.tmp.us; - @$(ECHO) $(subst .java,'\n',$(US_Resources_java)) >> $@.tmp.us; - @$(ECHO) $(subst .properties,'\n',$(NonUS_Resources_properties)) > $@.tmp.nonus; - @$(ECHO) $(subst .java,'\n',$(NonUS_Resources_java)) >> $@.tmp.nonus; + @$(ECHO) $(subst .properties,'\n',$(EN_Resources_properties)) > $@.tmp.en; + @$(ECHO) $(subst .java,'\n',$(EN_Resources_java)) >> $@.tmp.en; + @$(ECHO) $(subst .properties,'\n',$(NonEN_Resources_properties)) > $@.tmp.nonen; + @$(ECHO) $(subst .java,'\n',$(NonEN_Resources_java)) >> $@.tmp.nonen; NAWK="$(NAWK)" SED="$(SED)" SORT="$(SORT)" \ - $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.us \ - $@.tmp.nonus $< $@ - @$(RM) $@.tmp.us $@.tmp.nonus; + $(SH) $(LOCALEGEN_SH) $(RESOURCE_NAMES) $@.tmp.en \ + $@.tmp.nonen $< $@ + @$(RM) $@.tmp.en $@.tmp.nonen; endif genlocales : $(LocaleDataMetaInfo_Dest) diff --git a/jdk/make/java/java/localegen.sh b/jdk/make/java/java/localegen.sh index 8fad25ef534..78493d31f95 100644 --- a/jdk/make/java/java/localegen.sh +++ b/jdk/make/java/java/localegen.sh @@ -35,11 +35,11 @@ # A list of resource base name list; RESOURCE_NAMES=$1 -# A list of US resources; -US_FILES_LIST=$2 +# A list of EN resources; +EN_FILES_LIST=$2 -# A list of non-US resources; -NONUS_FILES_LIST=$3 +# A list of non-EN resources; +NONEN_FILES_LIST=$3 INPUT_FILE=$4 OUTPUT_FILE=$5 @@ -53,23 +53,23 @@ getlocalelist() { sed_script="$SED -e \"s@^#warn .*@// -- This file was mechanically generated: Do not edit! -- //@\" " # ja-JP-JP and th-TH-TH need to be manually added, as they don't have any resource files. -nonusall=" ja-JP-JP th-TH-TH " +nonenall=" ja-JP-JP th-TH-TH " for FILE in $RESOURCE_NAMES do - getlocalelist $FILE $US_FILES_LIST - sed_script=$sed_script"-e \"s@#"$FILE"_USLocales#@$localelist@g\" " - usall=$usall" "$localelist - getlocalelist $FILE $NONUS_FILES_LIST - sed_script=$sed_script"-e \"s@#"$FILE"_NonUSLocales#@$localelist@g\" " - nonusall=$nonusall" "$localelist + getlocalelist $FILE $EN_FILES_LIST + sed_script=$sed_script"-e \"s@#"$FILE"_ENLocales#@$localelist@g\" " + enall=$enall" "$localelist + getlocalelist $FILE $NONEN_FILES_LIST + sed_script=$sed_script"-e \"s@#"$FILE"_NonENLocales#@$localelist@g\" " + nonenall=$nonenall" "$localelist done -usall=`(for LOC in $usall; do echo $LOC;done) |$SORT -u` -nonusall=`(for LOC in $nonusall; do echo $LOC;done) |$SORT -u` +enall=`(for LOC in $enall; do echo $LOC;done) |$SORT -u` +nonenall=`(for LOC in $nonenall; do echo $LOC;done) |$SORT -u` -sed_script=$sed_script"-e \"s@#AvailableLocales_USLocales#@$usall@g\" " -sed_script=$sed_script"-e \"s@#AvailableLocales_NonUSLocales#@$nonusall@g\" " +sed_script=$sed_script"-e \"s@#AvailableLocales_ENLocales#@$enall@g\" " +sed_script=$sed_script"-e \"s@#AvailableLocales_NonENLocales#@$nonenall@g\" " sed_script=$sed_script"$INPUT_FILE > $OUTPUT_FILE" eval $sed_script diff --git a/jdk/make/java/text/base/FILES_java.gmk b/jdk/make/java/text/base/FILES_java.gmk index c2e0f479c6b..47abc6ff095 100644 --- a/jdk/make/java/text/base/FILES_java.gmk +++ b/jdk/make/java/text/base/FILES_java.gmk @@ -107,5 +107,17 @@ FILES_java = \ sun/text/resources/FormatData.java \ sun/text/resources/JavaTimeSupplementary.java \ sun/text/resources/en/FormatData_en.java \ + sun/text/resources/en/FormatData_en_AU.java \ + sun/text/resources/en/FormatData_en_CA.java \ + sun/text/resources/en/FormatData_en_GB.java \ + sun/text/resources/en/FormatData_en_IE.java \ + sun/text/resources/en/FormatData_en_IN.java \ + sun/text/resources/en/FormatData_en_MT.java \ + sun/text/resources/en/FormatData_en_NZ.java \ + sun/text/resources/en/FormatData_en_PH.java \ + sun/text/resources/en/FormatData_en_SG.java \ sun/text/resources/en/FormatData_en_US.java \ + sun/text/resources/en/FormatData_en_ZA.java \ sun/text/resources/en/JavaTimeSupplementary_en.java \ + sun/text/resources/en/JavaTimeSupplementary_en_GB.java \ + sun/text/resources/en/JavaTimeSupplementary_en_SG.java diff --git a/jdk/make/java/util/FILES_java.gmk b/jdk/make/java/util/FILES_java.gmk index 677a97c52cb..75bbe38031c 100644 --- a/jdk/make/java/util/FILES_java.gmk +++ b/jdk/make/java/util/FILES_java.gmk @@ -30,4 +30,7 @@ FILES_java = \ sun/util/resources/LocaleNamesBundle.java \ sun/util/resources/TimeZoneNamesBundle.java \ sun/util/resources/TimeZoneNames.java \ - sun/util/resources/en/TimeZoneNames_en.java + sun/util/resources/en/TimeZoneNames_en.java \ + sun/util/resources/en/TimeZoneNames_en_CA.java \ + sun/util/resources/en/TimeZoneNames_en_GB.java \ + sun/util/resources/en/TimeZoneNames_en_IE.java diff --git a/jdk/make/java/util/FILES_properties.gmk b/jdk/make/java/util/FILES_properties.gmk index 4b777c5f2d8..e2fc3cb118b 100644 --- a/jdk/make/java/util/FILES_properties.gmk +++ b/jdk/make/java/util/FILES_properties.gmk @@ -26,9 +26,25 @@ FILES_compiled_properties = \ sun/util/resources/LocaleNames.properties \ sun/util/resources/en/LocaleNames_en.properties \ + sun/util/resources/en/LocaleNames_en_MT.properties \ + sun/util/resources/en/LocaleNames_en_PH.properties \ + sun/util/resources/en/LocaleNames_en_SG.properties \ \ sun/util/resources/CalendarData.properties \ sun/util/resources/en/CalendarData_en.properties \ + sun/util/resources/en/CalendarData_en_GB.properties \ + sun/util/resources/en/CalendarData_en_IE.properties \ + sun/util/resources/en/CalendarData_en_MT.properties \ \ sun/util/resources/CurrencyNames.properties \ - sun/util/resources/en/CurrencyNames_en_US.properties + sun/util/resources/en/CurrencyNames_en_AU.properties \ + sun/util/resources/en/CurrencyNames_en_CA.properties \ + sun/util/resources/en/CurrencyNames_en_GB.properties \ + sun/util/resources/en/CurrencyNames_en_IE.properties \ + sun/util/resources/en/CurrencyNames_en_IN.properties \ + sun/util/resources/en/CurrencyNames_en_MT.properties \ + sun/util/resources/en/CurrencyNames_en_NZ.properties \ + sun/util/resources/en/CurrencyNames_en_PH.properties \ + sun/util/resources/en/CurrencyNames_en_SG.properties \ + sun/util/resources/en/CurrencyNames_en_US.properties \ + sun/util/resources/en/CurrencyNames_en_ZA.properties diff --git a/jdk/make/javax/sound/jsoundds/Makefile b/jdk/make/javax/sound/jsoundds/Makefile index f476b39811a..a747d699a0a 100644 --- a/jdk/make/javax/sound/jsoundds/Makefile +++ b/jdk/make/javax/sound/jsoundds/Makefile @@ -55,8 +55,7 @@ FILES_export = \ LDLIBS += dsound.lib winmm.lib user32.lib ole32.lib CPPFLAGS += \ -DUSE_DAUDIO=TRUE \ - -I$(SHARE_SRC)/native/com/sun/media/sound \ - -I$(DXSDK_INCLUDE_PATH) + -I$(SHARE_SRC)/native/com/sun/media/sound # # Add to the ambient VPATH. diff --git a/jdk/make/jdk_generic_profile.sh b/jdk/make/jdk_generic_profile.sh index 28705393a33..1103a56aa52 100644 --- a/jdk/make/jdk_generic_profile.sh +++ b/jdk/make/jdk_generic_profile.sh @@ -80,7 +80,6 @@ # ALT_BOOTDIR # Windows Only: # ALT_UNIXCOMMAND_PATH -# ALT_DXSDK_PATH # ALT_MSVCRNN_DLL_PATH # ############################################################################# diff --git a/jdk/make/netbeans/awt2d/README b/jdk/make/netbeans/awt2d/README index 040c9e76919..4df566dd157 100644 --- a/jdk/make/netbeans/awt2d/README +++ b/jdk/make/netbeans/awt2d/README @@ -39,7 +39,6 @@ Here are the steps: (on Windows): #>env | grep ALT ALT_JDK_IMPORT_PATH=c:/devtools/java/jdk1.7.0 - ALT_DXSDK_PATH=c:/devtools/DirectX/DXSDK_Dec06 ALT_BOOTDIR=c:/DevTools/java/jdk1.6.0 If your build is a FASTDEBUG build, don't forget @@ -50,7 +49,6 @@ Here are the steps: accordingly: make.options=\ ALT_JDK_IMPORT_PATH=c:/devtools/java/jdk1.7.0 \ - ALT_DXSDK_PATH=c:/devtools/DirectX/DXSDK_Dec06 \ ALT_BOOTDIR=c:/DevTools/java/jdk1.6.0 \ FASTDEBUG=true make=c:/devtools/cygwin/bin/make @@ -175,7 +173,6 @@ Notes on using CND (C/C++ pack) with this project and NetBeans. ../../build/windows-i586/tmp/sun/sun.awt/splashscreen/CClassHeaders; ../../build/windows-i586/tmp/sun/sun.font/fontmanager/CClassHeaders; ../../build/windows-i586/tmp/sun/sun.font/t2k/CClassHeaders; - C:/DevTools/DirectX/DXSDK_Dec06/Include; C:/devtools/VS2003/SDK/v1.1/include; C:/devtools/VS2003/VC7/ATLMFC/INCLUDE; C:/devtools/VS2003/VC7/INCLUDE; @@ -188,7 +185,7 @@ Notes on using CND (C/C++ pack) with this project and NetBeans. Note that most paths are relative to the native project directory - this helps if you decide to relocate the workspace later. The ones that aren't relative are paths to external include directories, like those - of the Platform SDK, DirectX SDK. + of the Platform SDK. On Unix platforms these may be directories like /usr/include. The parser must know some defines to correctly parse the source files, diff --git a/jdk/make/sun/awt/Makefile b/jdk/make/sun/awt/Makefile index dc4c250cf74..8b7612e416a 100644 --- a/jdk/make/sun/awt/Makefile +++ b/jdk/make/sun/awt/Makefile @@ -564,7 +564,6 @@ OTHER_INCLUDES += -I$(CLASSHDRDIR)/../../java/jvm \ -I$(OBJDIR) \ -I$(SHARE_SRC)/native/common \ -I$(WINAWT_native) \ - -I$(DXSDK_INCLUDE_PATH) \ -I$(SHARE_SRC)/native/sun/awt/image/cvutils \ -I$(SHARE_SRC)/native/sun/awt/image \ -I$(SHARE_SRC)/native/sun/java2d/loops \ diff --git a/jdk/make/sun/cmm/lcms/mapfile-vers b/jdk/make/sun/cmm/lcms/mapfile-vers index 3d9074f746d..949ff9b5787 100644 --- a/jdk/make/sun/cmm/lcms/mapfile-vers +++ b/jdk/make/sun/cmm/lcms/mapfile-vers @@ -28,9 +28,8 @@ SUNWprivate_1.1 { global: Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; - Java_sun_java2d_cmm_lcms_LCMS_getProfileData; + Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative; + Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative; Java_sun_java2d_cmm_lcms_LCMS_getTagNative; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_colorConvert; diff --git a/jdk/make/sun/jawt/Makefile b/jdk/make/sun/jawt/Makefile index 718fb33c499..0520fc17bf1 100644 --- a/jdk/make/sun/jawt/Makefile +++ b/jdk/make/sun/jawt/Makefile @@ -69,7 +69,6 @@ OTHER_CXXFLAGS += $(GX_OPTION) -DUNICODE -D_UNICODE # Other extra flags needed for compiling. # CPPFLAGS += -I$(SHARE_SRC)/native/common \ - -I$(DXSDK_INCLUDE_PATH) \ -I$(PLATFORM_SRC)/native/sun/windows \ -I$(CLASSHDRDIR)/../../awt/CClassHeaders \ -I$(SHARE_SRC)/native/sun/awt/debug \ diff --git a/jdk/make/sun/text/FILES_java.gmk b/jdk/make/sun/text/FILES_java.gmk index 2f15ec33612..dbb4856c673 100644 --- a/jdk/make/sun/text/FILES_java.gmk +++ b/jdk/make/sun/text/FILES_java.gmk @@ -96,16 +96,6 @@ FILES_java = \ sun/text/resources/el/FormatData_el.java \ sun/text/resources/el/FormatData_el_CY.java \ sun/text/resources/el/FormatData_el_GR.java \ - sun/text/resources/en/FormatData_en_AU.java \ - sun/text/resources/en/FormatData_en_CA.java \ - sun/text/resources/en/FormatData_en_GB.java \ - sun/text/resources/en/FormatData_en_IE.java \ - sun/text/resources/en/FormatData_en_IN.java \ - sun/text/resources/en/FormatData_en_MT.java \ - sun/text/resources/en/FormatData_en_NZ.java \ - sun/text/resources/en/FormatData_en_PH.java \ - sun/text/resources/en/FormatData_en_SG.java \ - sun/text/resources/en/FormatData_en_ZA.java \ sun/text/resources/es/FormatData_es.java \ sun/text/resources/es/FormatData_es_BO.java \ sun/text/resources/es/FormatData_es_AR.java \ @@ -214,9 +204,6 @@ FILES_java = \ sun/util/resources/zh/CurrencyNames_zh_SG.java \ sun/util/resources/zh/LocaleNames_zh_HK.java \ sun/util/resources/de/TimeZoneNames_de.java \ - sun/util/resources/en/TimeZoneNames_en_CA.java \ - sun/util/resources/en/TimeZoneNames_en_GB.java \ - sun/util/resources/en/TimeZoneNames_en_IE.java \ sun/util/resources/es/TimeZoneNames_es.java \ sun/util/resources/fr/TimeZoneNames_fr.java \ sun/util/resources/hi/TimeZoneNames_hi.java \ @@ -237,8 +224,6 @@ FILES_java = \ sun/text/resources/da/JavaTimeSupplementary_da.java \ sun/text/resources/de/JavaTimeSupplementary_de.java \ sun/text/resources/el/JavaTimeSupplementary_el.java \ - sun/text/resources/en/JavaTimeSupplementary_en_GB.java \ - sun/text/resources/en/JavaTimeSupplementary_en_SG.java \ sun/text/resources/es/JavaTimeSupplementary_es.java \ sun/text/resources/et/JavaTimeSupplementary_et.java \ sun/text/resources/fi/JavaTimeSupplementary_fi.java \ diff --git a/jdk/make/sun/text/FILES_properties.gmk b/jdk/make/sun/text/FILES_properties.gmk index a3a1321cfb9..494d6cc4b19 100644 --- a/jdk/make/sun/text/FILES_properties.gmk +++ b/jdk/make/sun/text/FILES_properties.gmk @@ -33,9 +33,6 @@ FILES_compiled_properties = \ sun/util/resources/de/LocaleNames_de.properties \ sun/util/resources/el/LocaleNames_el.properties \ sun/util/resources/el/LocaleNames_el_CY.properties \ - sun/util/resources/en/LocaleNames_en_MT.properties \ - sun/util/resources/en/LocaleNames_en_PH.properties \ - sun/util/resources/en/LocaleNames_en_SG.properties \ sun/util/resources/es/LocaleNames_es.properties \ sun/util/resources/es/LocaleNames_es_US.properties \ sun/util/resources/et/LocaleNames_et.properties \ @@ -88,9 +85,6 @@ FILES_compiled_properties = \ sun/util/resources/de/CalendarData_de.properties \ sun/util/resources/el/CalendarData_el.properties \ sun/util/resources/el/CalendarData_el_CY.properties \ - sun/util/resources/en/CalendarData_en_GB.properties \ - sun/util/resources/en/CalendarData_en_IE.properties \ - sun/util/resources/en/CalendarData_en_MT.properties \ sun/util/resources/es/CalendarData_es.properties \ sun/util/resources/es/CalendarData_es_ES.properties \ sun/util/resources/es/CalendarData_es_US.properties \ @@ -164,16 +158,6 @@ FILES_compiled_properties = \ sun/util/resources/de/CurrencyNames_de_LU.properties \ sun/util/resources/el/CurrencyNames_el_CY.properties \ sun/util/resources/el/CurrencyNames_el_GR.properties \ - sun/util/resources/en/CurrencyNames_en_AU.properties \ - sun/util/resources/en/CurrencyNames_en_CA.properties \ - sun/util/resources/en/CurrencyNames_en_GB.properties \ - sun/util/resources/en/CurrencyNames_en_IE.properties \ - sun/util/resources/en/CurrencyNames_en_IN.properties \ - sun/util/resources/en/CurrencyNames_en_MT.properties \ - sun/util/resources/en/CurrencyNames_en_NZ.properties \ - sun/util/resources/en/CurrencyNames_en_PH.properties \ - sun/util/resources/en/CurrencyNames_en_SG.properties \ - sun/util/resources/en/CurrencyNames_en_ZA.properties \ sun/util/resources/es/CurrencyNames_es.properties \ sun/util/resources/es/CurrencyNames_es_AR.properties \ sun/util/resources/es/CurrencyNames_es_BO.properties \ diff --git a/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java b/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java index 0872100b7db..833a835c0ce 100644 --- a/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java +++ b/jdk/make/tools/src/build/tools/generatecharacter/CharacterName.java @@ -11,7 +11,7 @@ public class CharacterName { FileReader reader = null; try { if (args.length != 2) { - System.err.println("Usage: java CharacterName UniocdeData.txt uniName.dat"); + System.err.println("Usage: java CharacterName UnicodeData.txt uniName.dat"); System.exit(1); } diff --git a/jdk/makefiles/CompileNativeLibraries.gmk b/jdk/makefiles/CompileNativeLibraries.gmk index 656ee3c4841..8c59cecc4f7 100644 --- a/jdk/makefiles/CompileNativeLibraries.gmk +++ b/jdk/makefiles/CompileNativeLibraries.gmk @@ -211,6 +211,7 @@ ifneq ($(OPENJDK_TARGET_OS),macosx) LIBJAVA_EXCLUDE_FILES += java_props_macosx.c else BUILD_LIBJAVA_java_props_md.c_CFLAGS:=-x objective-c + BUILD_LIBJAVA_java_props_macosx.c_CFLAGS:=-x objective-c endif ifeq ($(OPENJDK_TARGET_OS),windows) @@ -252,6 +253,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJAVA,\ LDFLAGS_SUFFIX_linux:=$(LIBDL) $(BUILD_LIBFDLIBM),\ LDFLAGS_SUFFIX_macosx:=-L$(JDK_OUTPUTDIR)/objs/ -lfdlibm \ -framework CoreFoundation \ + -framework Foundation \ -framework Security -framework SystemConfiguration, \ LDFLAGS_SUFFIX_windows:=-export:winFileHandleOpen -export:handleLseek \ jvm.lib $(BUILD_LIBFDLIBM) $(WIN_VERIFY_LIB) \ @@ -472,7 +474,6 @@ ifeq ($(OPENJDK_TARGET_OS),windows) $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/windows \ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/d3d - LIBAWT_CFLAGS+=-I$(DXSDK_INCLUDE_PATH) else LIBAWT_DIRS+=\ $(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/x11 @@ -1482,8 +1483,7 @@ ifeq ($(OPENJDK_TARGET_OS), windows) -I$(JDK_TOPDIR)/src/share/native/sun/awt/debug \ -I$(JDK_TOPDIR)/src/share/native/sun/java2d \ -I$(JDK_TOPDIR)/src/share/native/sun/awt/image/cvutils \ - -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows \ - -I$(DXSDK_INCLUDE_PATH), \ + -I$(JDK_TOPDIR)/src/$(OPENJDK_TARGET_OS_API_DIR)/native/sun/java2d/windows, \ LDFLAGS:=$(LDFLAGS_JDKLIB) $(KERNEL32_LIB) $(LDFLAGS_CXX_JDK) \ advapi32.lib $(WIN_AWT_LIB),\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX),\ @@ -2961,8 +2961,7 @@ $(eval $(call SetupNativeCompilation,BUILD_LIBJSOUNDDS,\ OPTIMIZATION:=LOW, \ CFLAGS:=$(CFLAGS_JDKLIB) \ $(LIBJSOUND_CFLAGS) \ - -DUSE_DAUDIO=TRUE \ - -I$(DXSDK_INCLUDE_PATH), \ + -DUSE_DAUDIO=TRUE, \ LDFLAGS:=$(LDFLAGS_JDKLIB) $(LDFLAGS_CXX_JDK) \ $(call SET_SHARED_LIBRARY_ORIGIN),\ LDFLAGS_SUFFIX:=$(LDFLAGS_JDKLIB_SUFFIX) dsound.lib winmm.lib user32.lib ole32.lib,\ diff --git a/jdk/makefiles/CreateJars.gmk b/jdk/makefiles/CreateJars.gmk index 54531f19ef5..e1d0a5d311b 100644 --- a/jdk/makefiles/CreateJars.gmk +++ b/jdk/makefiles/CreateJars.gmk @@ -80,39 +80,6 @@ LOCALEDATA_INCLUDE_LOCALES := ar be bg ca cs da de el es et fi fr ga hi hr hu in LOCALEDATA_INCLUDES := $(addprefix sun/text/resources/,$(LOCALEDATA_INCLUDE_LOCALES)) \ $(addprefix sun/util/resources/,$(LOCALEDATA_INCLUDE_LOCALES)) -# For non-US English locale data - -LOCALEDATA_INCLUDES += \ - sun/text/resources/en/FormatData_en_AU.class \ - sun/text/resources/en/FormatData_en_CA.class \ - sun/text/resources/en/FormatData_en_GB.class \ - sun/text/resources/en/FormatData_en_IE.class \ - sun/text/resources/en/FormatData_en_IN.class \ - sun/text/resources/en/FormatData_en_MT.class \ - sun/text/resources/en/FormatData_en_NZ.class \ - sun/text/resources/en/FormatData_en_PH.class \ - sun/text/resources/en/FormatData_en_SG.class \ - sun/text/resources/en/FormatData_en_ZA.class \ - sun/util/resources/en/CalendarData_en_GB.class \ - sun/util/resources/en/CalendarData_en_IE.class \ - sun/util/resources/en/CalendarData_en_MT.class \ - sun/util/resources/en/CurrencyNames_en_AU.class \ - sun/util/resources/en/CurrencyNames_en_CA.class \ - sun/util/resources/en/CurrencyNames_en_GB.class \ - sun/util/resources/en/CurrencyNames_en_IE.class \ - sun/util/resources/en/CurrencyNames_en_IN.class \ - sun/util/resources/en/CurrencyNames_en_MT.class \ - sun/util/resources/en/CurrencyNames_en_NZ.class \ - sun/util/resources/en/CurrencyNames_en_PH.class \ - sun/util/resources/en/CurrencyNames_en_SG.class \ - sun/util/resources/en/CurrencyNames_en_ZA.class \ - sun/util/resources/en/LocaleNames_en_MT.class \ - sun/util/resources/en/LocaleNames_en_PH.class \ - sun/util/resources/en/LocaleNames_en_SG.class \ - sun/util/resources/en/TimeZoneNames_en_CA.class \ - sun/util/resources/en/TimeZoneNames_en_GB.class \ - sun/util/resources/en/TimeZoneNames_en_IE.class - $(eval $(call SetupArchive,BUILD_LOCALEDATA_JAR,,\ SRCS:=$(JDK_OUTPUTDIR)/classes,\ SUFFIXES:=.class _dict _th,\ diff --git a/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk b/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk index 306276adf59..1577017b7f2 100644 --- a/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk +++ b/jdk/makefiles/GensrcLocaleDataMetaInfo.gmk @@ -50,27 +50,27 @@ ifneq (,$(MISSING_RESOURCES)$(NEW_RESOURCES)) $(shell $(RM) $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java) endif -# The US locales -US_LOCALES:=en en-US +# The EN locales +EN_LOCALES:=en% # ja-JP-JP and th-TH-TH need to be manually added, as they don't have any resource files. -ALL_NON_US_LOCALES:=ja-JP-JP th-TH-TH +ALL_NON_EN_LOCALES:=ja-JP-JP th-TH-TH SED_ARGS:=-e 's|$(HASH)warn This file is preprocessed before being compiled|// -- This file was mechanically generated: Do not edit! -- //|g' # This macro creates a sed expression that substitues for example: -# #FormatData_USLocales# with: en and/or en_US. +# #FormatData_ENLocales# with: en% locales. define CaptureLocale $1_LOCALES := $$(subst _,-,$$(filter-out $1,$$(subst $1_,,$$(filter $1_%,$(LOCALE_RESOURCES))))) - $1_US_LOCALES := $$(filter $(US_LOCALES),$$($1_LOCALES)) - $1_NON_US_LOCALES := $$(filter-out $(US_LOCALES),$$($1_LOCALES)) + $1_EN_LOCALES := $$(filter $(EN_LOCALES),$$($1_LOCALES)) + $1_NON_EN_LOCALES := $$(filter-out $(EN_LOCALES),$$($1_LOCALES)) - ALL_US_LOCALES += $$($1_US_LOCALES) - ALL_NON_US_LOCALES += $$($1_NON_US_LOCALES) + ALL_EN_LOCALES += $$($1_EN_LOCALES) + ALL_NON_EN_LOCALES += $$($1_NON_EN_LOCALES) # Don't sed in a space if there are no locales. - SED_ARGS+= -e 's/$$(HASH)$1_USLocales$$(HASH)/$$(if $$($1_US_LOCALES),$$(SPACE)$$($1_US_LOCALES),)/g' - SED_ARGS+= -e 's/$$(HASH)$1_NonUSLocales$$(HASH)/$$(if $$($1_NON_US_LOCALES),$$(SPACE)$$($1_NON_US_LOCALES),)/g' + SED_ARGS+= -e 's/$$(HASH)$1_ENLocales$$(HASH)/$$(if $$($1_EN_LOCALES),$$(SPACE)$$($1_EN_LOCALES),)/g' + SED_ARGS+= -e 's/$$(HASH)$1_NonENLocales$$(HASH)/$$(if $$($1_NON_EN_LOCALES),$$(SPACE)$$($1_NON_EN_LOCALES),)/g' endef #sun.text.resources.FormatData @@ -91,8 +91,8 @@ $(eval $(call CaptureLocale,CurrencyNames)) #sun.util.resources.CalendarData $(eval $(call CaptureLocale,CalendarData)) -SED_ARGS+= -e 's/$(HASH)AvailableLocales_USLocales$(HASH)/$(sort $(ALL_US_LOCALES))/g' -SED_ARGS+= -e 's/$(HASH)AvailableLocales_NonUSLocales$(HASH)/$(sort $(ALL_NON_US_LOCALES))/g' +SED_ARGS+= -e 's/$(HASH)AvailableLocales_ENLocales$(HASH)/$(sort $(ALL_EN_LOCALES))/g' +SED_ARGS+= -e 's/$(HASH)AvailableLocales_NonENLocales$(HASH)/$(sort $(ALL_NON_EN_LOCALES))/g' $(JDK_OUTPUTDIR)/gensrc/sun/util/locale/provider/LocaleDataMetaInfo.java: \ $(JDK_TOPDIR)/src/share/classes/sun/util/locale/provider/LocaleDataMetaInfo-XLocales.java.template diff --git a/jdk/makefiles/Setup.gmk b/jdk/makefiles/Setup.gmk index 8012e547b55..4da575fed1a 100644 --- a/jdk/makefiles/Setup.gmk +++ b/jdk/makefiles/Setup.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,10 @@ DISABLE_WARNINGS:=-Xlint:all,-deprecation,-unchecked,-rawtypes,-cast,-serial,-dep-ann,-static,-fallthrough,-try,-varargs,-empty,-finally +# To build with all warnings enabled, do the following: +# make JAVAC_WARNINGS="-Xlint:all -Xmaxwarns 10000" +JAVAC_WARNINGS:=-Xlint:-unchecked,-deprecation,-overrides,classfile,dep-ann,divzero,varargs -Werror + # The generate old bytecode javac setup uses the new compiler to compile for the # boot jdk to generate tools that need to be run with the boot jdk. # Thus we force the target bytecode to 7. @@ -41,7 +45,7 @@ $(eval $(call SetupJavaCompiler,GENERATE_JDKBYTECODE,\ JVM:=$(JAVA),\ JAVAC:=$(NEW_JAVAC),\ FLAGS:=-bootclasspath $(JDK_OUTPUTDIR)/classes -source 8 -target 8 \ - -encoding ascii -XDignore.symbol.file=true $(DISABLE_WARNINGS) \ + -encoding ascii -XDignore.symbol.file=true $(JAVAC_WARNINGS) \ $(GENERATE_JDKBYTECODE_EXTRA_FLAGS),\ SERVER_DIR:=$(SJAVAC_SERVER_DIR),\ SERVER_JVM:=$(SJAVAC_SERVER_JAVA))) diff --git a/jdk/makefiles/mapfiles/liblcms/mapfile-vers b/jdk/makefiles/mapfiles/liblcms/mapfile-vers index 024511423d3..2e63d68e5d4 100644 --- a/jdk/makefiles/mapfiles/liblcms/mapfile-vers +++ b/jdk/makefiles/mapfiles/liblcms/mapfile-vers @@ -28,9 +28,8 @@ SUNWprivate_1.1 { global: Java_sun_java2d_cmm_lcms_LCMS_loadProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_freeProfileNative; - Java_sun_java2d_cmm_lcms_LCMS_getProfileSize; - Java_sun_java2d_cmm_lcms_LCMS_getProfileData; + Java_sun_java2d_cmm_lcms_LCMS_getProfileSizeNative; + Java_sun_java2d_cmm_lcms_LCMS_getProfileDataNative; Java_sun_java2d_cmm_lcms_LCMS_getTagNative; Java_sun_java2d_cmm_lcms_LCMS_setTagDataNative; Java_sun_java2d_cmm_lcms_LCMS_colorConvert; diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java index fb7032f0b74..9765066d9d2 100644 --- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java +++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java @@ -38,6 +38,7 @@ import java.util.*; import sun.awt.*; import sun.lwawt.macosx.*; import sun.print.*; +import sun.security.util.SecurityConstants; public abstract class LWToolkit extends SunToolkit implements Runnable { @@ -502,7 +503,7 @@ public abstract class LWToolkit extends SunToolkit implements Runnable { public Clipboard getSystemClipboard() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkSystemClipboardAccess(); + security.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); } synchronized (this) { diff --git a/jdk/src/macosx/native/sun/awt/CTextPipe.m b/jdk/src/macosx/native/sun/awt/CTextPipe.m index d9bf48afd92..f6510f204ae 100644 --- a/jdk/src/macosx/native/sun/awt/CTextPipe.m +++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m @@ -145,11 +145,6 @@ void JavaCT_DrawGlyphVector BOOL saved = false; - /* Save and restore of graphics context is done before the iteration. - This seems to work using our test case (see bug ID 7158350) so we are restoring it at - the end of the for loop. If we find out that save/restore outside the loop - doesn't work on all cases then we will move the Save/Restore inside the loop.*/ - CGContextSaveGState(cgRef); CGAffineTransform invTx = CGAffineTransformInvert(strike->fTx); NSUInteger i; @@ -226,7 +221,9 @@ void JavaCT_DrawGlyphVector } // reset the font on the context after striking a unicode with CoreText - CGContextRestoreGState(cgRef); + if (saved) { + CGContextRestoreGState(cgRef); + } } // Using the Quartz Surface Data context, draw a hot-substituted character run diff --git a/jdk/src/share/classes/com/sun/nio/sctp/Association.java b/jdk/src/share/classes/com/sun/nio/sctp/Association.java index b367412b83f..965feae3418 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/Association.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/Association.java @@ -58,6 +58,13 @@ public class Association { /** * Initializes a new instance of this class. + * + * @param associationID + * The association ID + * @param maxInStreams + * The maximum number of inbound streams + * @param maxOutStreams + * The maximum number of outbound streams */ protected Association(int associationID, int maxInStreams, diff --git a/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java b/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java index 0dc063bd55c..b5a4137054d 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/IllegalReceiveException.java @@ -41,6 +41,9 @@ public class IllegalReceiveException extends IllegalStateException { /** * Constructs an instance of this class with the specified message. + * + * @param msg + * The String that contains a detailed message */ public IllegalReceiveException(String msg) { super(msg); diff --git a/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java b/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java index b48ef56b1b5..4088df34687 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/IllegalUnbindException.java @@ -41,6 +41,9 @@ public class IllegalUnbindException extends IllegalStateException { /** * Constructs an instance of this class with the specified detailed message. + * + * @param msg + * The String that contains a detailed message */ public IllegalUnbindException(String msg) { super(msg); diff --git a/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java b/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java index 40a818fe5bd..abe49f24593 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/InvalidStreamException.java @@ -40,6 +40,9 @@ public class InvalidStreamException extends IllegalArgumentException { /** * Constructs an instance of this class with the specified detailed message. + * + * @param msg + * The String that contains a detailed message */ public InvalidStreamException(String msg) { super(msg); diff --git a/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java b/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java index d7a2ee81563..997c6253834 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/MessageInfo.java @@ -48,7 +48,7 @@ import java.net.SocketAddress; * longer required to be sent after the time period expires. It is not a hard * timeout and may be influenced by whether the association supports the partial * reliability extension, RFC 3758 - * + * . * *

    {@code MessageInfo} instances are not safe for use by multiple concurrent * threads. If a MessageInfo is to be used by more than one thread then access diff --git a/jdk/src/share/classes/com/sun/nio/sctp/Notification.java b/jdk/src/share/classes/com/sun/nio/sctp/Notification.java index cc23b8f2e47..2436fae7ba7 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/Notification.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/Notification.java @@ -40,6 +40,8 @@ package com.sun.nio.sctp; public interface Notification { /** * Returns the association that this notification is applicable to. + * + * @return The association */ public Association association(); } diff --git a/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java b/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java index 0b351a4ca3f..22cf07650f4 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpChannel.java @@ -59,7 +59,7 @@ import java.nio.channels.SelectionKey; * {@link #setOption(SctpSocketOption,Object) setOption} method. An SCTP * channel support the following options: *

    - * + *
    * * * @@ -636,6 +636,9 @@ public abstract class SctpChannel /** * Returns the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -659,6 +662,9 @@ public abstract class SctpChannel /** * Sets the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -752,6 +758,9 @@ public abstract class SctpChannel * the {@code receive} method of this channel, if it does an * {@link IllegalReceiveException} will be thrown. * + * @param + * The type of the attachment + * * @param dst * The buffer into which message bytes are to be transferred * @@ -831,7 +840,7 @@ public abstract class SctpChannel * there was insufficient room for the message in the underlying * output buffer * - * @throws InvalidStreamExcepton + * @throws InvalidStreamException * If {@code streamNumner} is negative or greater than or equal to * the maximum number of outgoing streams * diff --git a/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java b/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java index f8745dba41e..42e56591e43 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpMultiChannel.java @@ -63,7 +63,7 @@ import java.nio.channels.SelectionKey; * {@link #setOption(SctpSocketOption,Object,Association) setOption} method. An * {@code SctpMultiChannel} supports the following options: *
    - *
    Option NameDescription
    + *
    * * * @@ -394,6 +394,9 @@ public abstract class SctpMultiChannel * Returns all of the remote addresses to which the given association on * this channel's socket is connected. * + * @param association + * The association + * * @return All of the remote addresses for the given association, or * an empty {@code Set} if the association has been shutdown * @@ -431,6 +434,9 @@ public abstract class SctpMultiChannel * ignored if given. However, if the option is association specific then the * association must be given. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -464,6 +470,9 @@ public abstract class SctpMultiChannel * ignored if given. However, if the option is association specific then the * association must be given. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -567,6 +576,9 @@ public abstract class SctpMultiChannel * the {@code receive} method of this channel, if it does an * {@link IllegalReceiveException} will be thrown. * + * @param + * The type of the attachment + * * @param buffer * The buffer into which bytes are to be transferred * @@ -673,7 +685,7 @@ public abstract class SctpMultiChannel * there was insufficient room for the message in the underlying * output buffer * - * @throws InvalidStreamExcepton + * @throws InvalidStreamException * If {@code streamNumber} is negative, or if an association already * exists and {@code streamNumber} is greater than the maximum number * of outgoing streams diff --git a/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java b/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java index 637df72d394..c96e516ca4d 100644 --- a/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java +++ b/jdk/src/share/classes/com/sun/nio/sctp/SctpServerChannel.java @@ -47,7 +47,7 @@ import java.nio.channels.spi.AbstractSelectableChannel; * {@link #setOption(SctpSocketOption,Object) setOption} method. SCTP server socket * channels support the following options: *
    - *
    Option NameDescription
    + *
    * * * @@ -345,6 +345,9 @@ public abstract class SctpServerChannel /** * Returns the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * @@ -367,6 +370,9 @@ public abstract class SctpServerChannel /** * Sets the value of a socket option. * + * @param + * The type of the socket option value + * * @param name * The socket option * diff --git a/jdk/src/share/classes/java/awt/TextComponent.java b/jdk/src/share/classes/java/awt/TextComponent.java index 7a6cd26bbf3..483657fd4ce 100644 --- a/jdk/src/share/classes/java/awt/TextComponent.java +++ b/jdk/src/share/classes/java/awt/TextComponent.java @@ -35,6 +35,7 @@ import java.text.BreakIterator; import javax.swing.text.AttributeSet; import javax.accessibility.*; import java.awt.im.InputMethodRequests; +import sun.security.util.SecurityConstants; /** * The TextComponent class is the superclass of @@ -728,7 +729,7 @@ public class TextComponent extends Component implements Accessible { SecurityManager sm = System.getSecurityManager(); if (sm == null) return true; try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); return true; } catch (SecurityException e) {} return false; diff --git a/jdk/src/share/classes/java/awt/Toolkit.java b/jdk/src/share/classes/java/awt/Toolkit.java index 92bedb7580b..32f0adab3bc 100644 --- a/jdk/src/share/classes/java/awt/Toolkit.java +++ b/jdk/src/share/classes/java/awt/Toolkit.java @@ -1270,12 +1270,8 @@ public abstract class Toolkit { *

    * Each actual implementation of this method should first check if there * is a security manager installed. If there is, the method should call - * the security manager's checkSystemClipboardAccess method - * to ensure it's ok to to access the system clipboard. If the default - * implementation of checkSystemClipboardAccess is used (that - * is, that method is not overriden), then this results in a call to the - * security manager's checkPermission method with an - * AWTPermission("accessClipboard") permission. + * the security manager's {@link SecurityManager#checkPermission + * checkPermission} method to check {@code AWTPermission("accessClipboard")}. * * @return the system Clipboard * @exception HeadlessException if GraphicsEnvironment.isHeadless() @@ -1318,14 +1314,9 @@ public abstract class Toolkit { * system selection Clipboard as described above. *

    * Each actual implementation of this method should first check if there - * is a SecurityManager installed. If there is, the method - * should call the SecurityManager's - * checkSystemClipboardAccess method to ensure that client - * code has access the system selection. If the default implementation of - * checkSystemClipboardAccess is used (that is, if the method - * is not overridden), then this results in a call to the - * SecurityManager's checkPermission method with - * an AWTPermission("accessClipboard") permission. + * is a security manager installed. If there is, the method should call + * the security manager's {@link SecurityManager#checkPermission + * checkPermission} method to check {@code AWTPermission("accessClipboard")}. * * @return the system selection as a Clipboard, or * null if the native platform does not support a @@ -1699,25 +1690,20 @@ public abstract class Toolkit { * therefore not assume that the EventQueue instance returned * by this method will be shared by other applets or the system. * - *

    First, if there is a security manager, its - * checkAwtEventQueueAccess - * method is called. - * If the default implementation of checkAwtEventQueueAccess - * is used (that is, that method is not overriden), then this results in - * a call to the security manager's checkPermission method - * with an AWTPermission("accessEventQueue") permission. + *

    If there is a security manager then its + * {@link SecurityManager#checkPermission checkPermission} method + * is called to check {@code AWTPermission("accessEventQueue")}. * * @return the EventQueue object * @throws SecurityException - * if a security manager exists and its {@link - * java.lang.SecurityManager#checkAwtEventQueueAccess} - * method denies access to the EventQueue + * if a security manager is set and it denies access to + * the {@code EventQueue} * @see java.awt.AWTPermission */ public final EventQueue getSystemEventQueue() { SecurityManager security = System.getSecurityManager(); if (security != null) { - security.checkAwtEventQueueAccess(); + security.checkPermission(SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION); } return getSystemEventQueueImpl(); } diff --git a/jdk/src/share/classes/java/awt/Window.java b/jdk/src/share/classes/java/awt/Window.java index 4076939c7f0..c10a3b277a8 100644 --- a/jdk/src/share/classes/java/awt/Window.java +++ b/jdk/src/share/classes/java/awt/Window.java @@ -195,10 +195,9 @@ public class Window extends Container implements Accessible { /** * This represents the warning message that is * to be displayed in a non secure window. ie : - * a window that has a security manager installed for - * which calling SecurityManager.checkTopLevelWindow() - * is false. This message can be displayed anywhere in - * the window. + * a window that has a security manager installed that denies + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * This message can be displayed anywhere in the window. * * @serial * @see #getWarningString @@ -417,11 +416,10 @@ public class Window extends Container implements Accessible { * Constructs a new, initially invisible window in default size with the * specified {@code GraphicsConfiguration}. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager, then it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")} + * to determine whether or not the window must be displayed with + * a warning banner. * * @param gc the {@code GraphicsConfiguration} of the target screen * device. If {@code gc} is {@code null}, the system default @@ -432,7 +430,6 @@ public class Window extends Container implements Accessible { * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow */ Window(GraphicsConfiguration gc) { init(gc); @@ -511,25 +508,16 @@ public class Window extends Container implements Accessible { /** * Constructs a new, initially invisible window in the default size. - * - *

    First, if there is a security manager, its - * {@code checkTopLevelWindow} - * method is called with {@code this} - * as its argument - * to see if it's ok to display the window without a warning banner. - * If the default implementation of {@code checkTopLevelWindow} - * is used (that is, that method is not overriden), then this results in - * a call to the security manager's {@code checkPermission} method - * with an {@code AWTPermission("showWindowWithoutWarningBanner")} - * permission. It that method raises a SecurityException, - * {@code checkTopLevelWindow} returns false, otherwise it - * returns true. If it returns false, a warning banner is created. + *

    + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a warning + * banner is created. * * @exception HeadlessException when * {@code GraphicsEnvironment.isHeadless()} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow */ Window() throws HeadlessException { GraphicsEnvironment.checkHeadless(); @@ -541,11 +529,10 @@ public class Window extends Container implements Accessible { * {@code Frame} as its owner. The window will not be focusable * unless its owner is showing on the screen. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a warning + * banner is created. * * @param owner the {@code Frame} to act as owner or {@code null} * if this window has no owner @@ -555,7 +542,6 @@ public class Window extends Container implements Accessible { * {@code GraphicsEnvironment.isHeadless} returns {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see #isShowing */ public Window(Frame owner) { @@ -570,11 +556,10 @@ public class Window extends Container implements Accessible { * unless its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. + * If that check fails with a {@code SecurityException} then a + * warning banner is created. * * @param owner the {@code Window} to act as owner or * {@code null} if this window has no owner @@ -585,7 +570,6 @@ public class Window extends Container implements Accessible { * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see #isShowing * * @since 1.2 @@ -603,11 +587,10 @@ public class Window extends Container implements Accessible { * its nearest owning {@code Frame} or {@code Dialog} * is showing on the screen. *

    - * If there is a security manager, this method first calls - * the security manager's {@code checkTopLevelWindow} - * method with {@code this} - * as its argument to determine whether or not the window - * must be displayed with a warning banner. + * If there is a security manager set, it is invoked to check + * {@code AWTPermission("showWindowWithoutWarningBanner")}. If that + * check fails with a {@code SecurityException} then a warning banner + * is created. * * @param owner the window to act as owner or {@code null} * if this window has no owner @@ -621,7 +604,6 @@ public class Window extends Container implements Accessible { * {@code true} * * @see java.awt.GraphicsEnvironment#isHeadless - * @see java.lang.SecurityManager#checkTopLevelWindow * @see GraphicsConfiguration#getBounds * @see #isShowing * @since 1.3 @@ -1362,10 +1344,9 @@ public class Window extends Container implements Accessible { * Gets the warning string that is displayed with this window. * If this window is insecure, the warning string is displayed * somewhere in the visible area of the window. A window is - * insecure if there is a security manager, and the security - * manager's {@code checkTopLevelWindow} method returns - * {@code false} when this window is passed to it as an - * argument. + * insecure if there is a security manager and the security + * manager denies + * {@code AWTPermission("showWindowWithoutWarningBanner")}. *

    * If the window is secure, then {@code getWarningString} * returns {@code null}. If the window is insecure, this @@ -1373,7 +1354,6 @@ public class Window extends Container implements Accessible { * {@code awt.appletWarning} * and returns the string value of that property. * @return the warning string for this window. - * @see java.lang.SecurityManager#checkTopLevelWindow(java.lang.Object) */ public final String getWarningString() { return warningString; @@ -1383,10 +1363,12 @@ public class Window extends Container implements Accessible { warningString = null; SecurityManager sm = System.getSecurityManager(); if (sm != null) { - if (!sm.checkTopLevelWindow(this)) { + try { + sm.checkPermission(SecurityConstants.AWT.TOPLEVEL_WINDOW_PERMISSION); + } catch (SecurityException se) { // make sure the privileged action is only // for getting the property! We don't want the - // above checkTopLevelWindow call to always succeed! + // above checkPermission call to always succeed! warningString = AccessController.doPrivileged( new GetPropertyAction("awt.appletWarning", "Java Applet Window")); diff --git a/jdk/src/share/classes/java/awt/color/ICC_Profile.java b/jdk/src/share/classes/java/awt/color/ICC_Profile.java index c1534249f39..7e44947477d 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_Profile.java +++ b/jdk/src/share/classes/java/awt/color/ICC_Profile.java @@ -37,6 +37,7 @@ package java.awt.color; import sun.java2d.cmm.PCMM; import sun.java2d.cmm.CMSManager; +import sun.java2d.cmm.Profile; import sun.java2d.cmm.ProfileDataVerifier; import sun.java2d.cmm.ProfileDeferralMgr; import sun.java2d.cmm.ProfileDeferralInfo; @@ -94,7 +95,7 @@ public class ICC_Profile implements Serializable { private static final long serialVersionUID = -3938515861990936766L; - transient long ID; + private transient Profile cmmProfile; private transient ProfileDeferralInfo deferralInfo; private transient ProfileActivator profileActivator; @@ -727,8 +728,8 @@ public class ICC_Profile implements Serializable { /** * Constructs an ICC_Profile object with a given ID. */ - ICC_Profile(long ID) { - this.ID = ID; + ICC_Profile(Profile p) { + this.cmmProfile = p; } @@ -751,8 +752,8 @@ public class ICC_Profile implements Serializable { * Frees the resources associated with an ICC_Profile object. */ protected void finalize () { - if (ID != 0) { - CMSManager.getModule().freeProfile(ID); + if (cmmProfile != null) { + CMSManager.getModule().freeProfile(cmmProfile); } else if (profileActivator != null) { ProfileDeferralMgr.unregisterDeferral(profileActivator); } @@ -770,7 +771,7 @@ public class ICC_Profile implements Serializable { public static ICC_Profile getInstance(byte[] data) { ICC_Profile thisProfile; - long theID; + Profile p = null; if (ProfileDeferralMgr.deferring) { ProfileDeferralMgr.activateProfiles(); @@ -779,32 +780,32 @@ public class ICC_Profile implements Serializable { ProfileDataVerifier.verify(data); try { - theID = CMSManager.getModule().loadProfile(data); + p = CMSManager.getModule().loadProfile(data); } catch (CMMException c) { throw new IllegalArgumentException("Invalid ICC Profile Data"); } try { - if ((getColorSpaceType (theID) == ColorSpace.TYPE_GRAY) && - (getData (theID, icSigMediaWhitePointTag) != null) && - (getData (theID, icSigGrayTRCTag) != null)) { - thisProfile = new ICC_ProfileGray (theID); + if ((getColorSpaceType (p) == ColorSpace.TYPE_GRAY) && + (getData (p, icSigMediaWhitePointTag) != null) && + (getData (p, icSigGrayTRCTag) != null)) { + thisProfile = new ICC_ProfileGray (p); } - else if ((getColorSpaceType (theID) == ColorSpace.TYPE_RGB) && - (getData (theID, icSigMediaWhitePointTag) != null) && - (getData (theID, icSigRedColorantTag) != null) && - (getData (theID, icSigGreenColorantTag) != null) && - (getData (theID, icSigBlueColorantTag) != null) && - (getData (theID, icSigRedTRCTag) != null) && - (getData (theID, icSigGreenTRCTag) != null) && - (getData (theID, icSigBlueTRCTag) != null)) { - thisProfile = new ICC_ProfileRGB (theID); + else if ((getColorSpaceType (p) == ColorSpace.TYPE_RGB) && + (getData (p, icSigMediaWhitePointTag) != null) && + (getData (p, icSigRedColorantTag) != null) && + (getData (p, icSigGreenColorantTag) != null) && + (getData (p, icSigBlueColorantTag) != null) && + (getData (p, icSigRedTRCTag) != null) && + (getData (p, icSigGreenTRCTag) != null) && + (getData (p, icSigBlueTRCTag) != null)) { + thisProfile = new ICC_ProfileRGB (p); } else { - thisProfile = new ICC_Profile (theID); + thisProfile = new ICC_Profile (p); } } catch (CMMException c) { - thisProfile = new ICC_Profile (theID); + thisProfile = new ICC_Profile (p); } return thisProfile; } @@ -1119,7 +1120,7 @@ public class ICC_Profile implements Serializable { fileName); } try { - ID = CMSManager.getModule().loadProfile(profileData); + cmmProfile = CMSManager.getModule().loadProfile(profileData); } catch (CMMException c) { ProfileDataException pde = new ProfileDataException("Invalid ICC Profile Data" + fileName); @@ -1229,14 +1230,14 @@ public class ICC_Profile implements Serializable { causing a deferred profile to be loaded */ } - return getColorSpaceType(ID); + return getColorSpaceType(cmmProfile); } - static int getColorSpaceType(long profileID) { + static int getColorSpaceType(Profile p) { byte[] theHeader; int theColorSpaceSig, theColorSpace; - theHeader = getData(profileID, icSigHead); + theHeader = getData(p, icSigHead); theColorSpaceSig = intFromBigEndian(theHeader, icHdrColorSpace); theColorSpace = iccCStoJCS (theColorSpaceSig); return theColorSpace; @@ -1258,15 +1259,15 @@ public class ICC_Profile implements Serializable { if (ProfileDeferralMgr.deferring) { ProfileDeferralMgr.activateProfiles(); } - return getPCSType(ID); + return getPCSType(cmmProfile); } - static int getPCSType(long profileID) { + static int getPCSType(Profile p) { byte[] theHeader; int thePCSSig, thePCS; - theHeader = getData(profileID, icSigHead); + theHeader = getData(p, icSigHead); thePCSSig = intFromBigEndian(theHeader, icHdrPcs); thePCS = iccCStoJCS(thePCSSig); return thePCS; @@ -1326,12 +1327,12 @@ public class ICC_Profile implements Serializable { PCMM mdl = CMSManager.getModule(); /* get the number of bytes needed for this profile */ - profileSize = mdl.getProfileSize(ID); + profileSize = mdl.getProfileSize(cmmProfile); profileData = new byte [profileSize]; /* get the data for the profile */ - mdl.getProfileData(ID, profileData); + mdl.getProfileData(cmmProfile, profileData); return profileData; } @@ -1358,11 +1359,11 @@ public class ICC_Profile implements Serializable { ProfileDeferralMgr.activateProfiles(); } - return getData(ID, tagSignature); + return getData(cmmProfile, tagSignature); } - static byte[] getData(long profileID, int tagSignature) { + static byte[] getData(Profile p, int tagSignature) { int tagSize; byte[] tagData; @@ -1370,12 +1371,12 @@ public class ICC_Profile implements Serializable { PCMM mdl = CMSManager.getModule(); /* get the number of bytes needed for this tag */ - tagSize = mdl.getTagSize(profileID, tagSignature); + tagSize = mdl.getTagSize(p, tagSignature); tagData = new byte[tagSize]; /* get an array for the tag */ /* get the tag's data */ - mdl.getTagData(profileID, tagSignature, tagData); + mdl.getTagData(p, tagSignature, tagData); } catch(CMMException c) { tagData = null; } @@ -1406,7 +1407,7 @@ public class ICC_Profile implements Serializable { ProfileDeferralMgr.activateProfiles(); } - CMSManager.getModule().setTagData(ID, tagSignature, tagData); + CMSManager.getModule().setTagData(cmmProfile, tagSignature, tagData); } /** diff --git a/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java b/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java index d9042266663..a868a6f50fc 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java +++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileGray.java @@ -35,7 +35,7 @@ package java.awt.color; -import java.awt.image.LookupTable; +import sun.java2d.cmm.Profile; import sun.java2d.cmm.ProfileDeferralInfo; /** @@ -76,8 +76,8 @@ extends ICC_Profile { /** * Constructs a new ICC_ProfileGray from a CMM ID. */ - ICC_ProfileGray(long ID) { - super(ID); + ICC_ProfileGray(Profile p) { + super(p); } /** diff --git a/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java b/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java index b0bad4d9a91..dcf65828650 100644 --- a/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java +++ b/jdk/src/share/classes/java/awt/color/ICC_ProfileRGB.java @@ -35,7 +35,7 @@ package java.awt.color; -import java.awt.image.LookupTable; +import sun.java2d.cmm.Profile; import sun.java2d.cmm.ProfileDeferralInfo; /** @@ -114,8 +114,8 @@ extends ICC_Profile { * @param ID The CMM ID for the profile. * */ - ICC_ProfileRGB(long ID) { - super(ID); + ICC_ProfileRGB(Profile p) { + super(p); } /** diff --git a/jdk/src/share/classes/java/awt/event/InputEvent.java b/jdk/src/share/classes/java/awt/event/InputEvent.java index 078b1a16d6a..24965d20caf 100644 --- a/jdk/src/share/classes/java/awt/event/InputEvent.java +++ b/jdk/src/share/classes/java/awt/event/InputEvent.java @@ -33,6 +33,7 @@ import java.util.Arrays; import sun.awt.AWTAccessor; import sun.util.logging.PlatformLogger; +import sun.security.util.SecurityConstants; /** * The root event class for all component-level input events. @@ -350,7 +351,7 @@ public abstract class InputEvent extends ComponentEvent { SecurityManager sm = System.getSecurityManager(); if (sm != null) { try { - sm.checkSystemClipboardAccess(); + sm.checkPermission(SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION); b = true; } catch (SecurityException se) { if (logger.isLoggable(PlatformLogger.Level.FINE)) { diff --git a/jdk/src/share/classes/java/io/Console.java b/jdk/src/share/classes/java/io/Console.java index c100f8a0ccd..292e42eec7c 100644 --- a/jdk/src/share/classes/java/io/Console.java +++ b/jdk/src/share/classes/java/io/Console.java @@ -124,9 +124,11 @@ public final class Console implements Flushable * {@link java.io.Reader#read(java.nio.CharBuffer) read(java.nio.CharBuffer)} * on the returned object will not read in characters beyond the line * bound for each invocation, even if the destination buffer has space for - * more characters. A line bound is considered to be any one of a line feed - * ('\n'), a carriage return ('\r'), a carriage return - * followed immediately by a linefeed, or an end of stream. + * more characters. The {@code Reader}'s {@code read} methods may block if a + * line bound has not been entered or reached on the console's input device. + * A line bound is considered to be any one of a line feed ('\n'), + * a carriage return ('\r'), a carriage return followed immediately + * by a linefeed, or an end of stream. * * @return The reader associated with this console */ diff --git a/jdk/src/share/classes/java/lang/AutoCloseable.java b/jdk/src/share/classes/java/lang/AutoCloseable.java index ce0fffe5939..be47cd0835f 100644 --- a/jdk/src/share/classes/java/lang/AutoCloseable.java +++ b/jdk/src/share/classes/java/lang/AutoCloseable.java @@ -26,7 +26,24 @@ package java.lang; /** - * A resource that must be closed when it is no longer needed. + * An object that may hold resources (such as file or socket handles) + * until it is closed. The {@link #close()} method of an {@code AutoCloseable} + * object is called automatically when exiting a {@code + * try}-with-resources block for which the object has been declared in + * the resource specification header. This construction ensures prompt + * release, avoiding resource exhaustion exceptions and errors that + * may otherwise occur. + * + * @apiNote + *

    It is possible, and in fact common, for a base class to + * implement AutoCloseable even though not all of its subclasses or + * instances will hold releasable resources. For code that must operate + * in complete generality, or when it is known that the {@code AutoCloseable} + * instance requires resource release, it is recommended to use {@code + * try}-with-resources constructions. However, when using facilities such as + * {@link java.util.stream.Stream} that support both I/O-based and + * non-I/O-based forms, {@code try}-with-resources blocks are in + * general unnecessary when using non-I/O-based forms. * * @author Josh Bloch * @since 1.7 diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index a3c962e0838..f884f2efe03 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -821,6 +821,10 @@ public final class Class implements java.io.Serializable, *

    If this object represents a primitive type or void, the method * returns an array of length 0. * + *

    If this {@code Class} object represents an array type, the + * interfaces {@code Cloneable} and {@code java.io.Serializable} are + * returned in that order. + * * @return an array of interfaces implemented by this class. */ public Class[] getInterfaces() { @@ -1484,22 +1488,24 @@ public final class Class implements java.io.Serializable, /** * Returns an array containing {@code Field} objects reflecting all * the accessible public fields of the class or interface represented by - * this {@code Class} object. The elements in the array returned are - * not sorted and are not in any particular order. This method returns an - * array of length 0 if the class or interface has no accessible public - * fields, or if it represents an array class, a primitive type, or void. + * this {@code Class} object. * - *

    Specifically, if this {@code Class} object represents a class, - * this method returns the public fields of this class and of all its - * superclasses. If this {@code Class} object represents an - * interface, this method returns the fields of this interface and of all - * its superinterfaces. + *

    If this {@code Class} object represents a class or interface with no + * no accessible public fields, then this method returns an array of length + * 0. * - *

    The implicit length field for array class is not reflected by this - * method. User code should use the methods of class {@code Array} to - * manipulate arrays. + *

    If this {@code Class} object represents a class, then this method + * returns the public fields of the class and of all its superclasses. * - *

    See The Java Language Specification, sections 8.2 and 8.3. + *

    If this {@code Class} object represents an interface, then this + * method returns the fields of the interface and of all its + * superinterfaces. + * + *

    If this {@code Class} object represents an array type, a primitive + * type, or void, then this method returns an array of length 0. + * + *

    The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Field} objects representing the * public fields @@ -1512,6 +1518,8 @@ public final class Class implements java.io.Serializable, * of this class. * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field[] getFields() throws SecurityException { @@ -1521,23 +1529,33 @@ public final class Class implements java.io.Serializable, /** - * Returns an array containing {@code Method} objects reflecting all - * the public member methods of the class or interface represented - * by this {@code Class} object, including those declared by the class - * or interface and those inherited from superclasses and - * superinterfaces. Array classes return all the (public) member methods - * inherited from the {@code Object} class. The elements in the array - * returned are not sorted and are not in any particular order. This - * method returns an array of length 0 if this {@code Class} object - * represents a class or interface that has no public member methods, or if - * this {@code Class} object represents a primitive type or void. + * Returns an array containing {@code Method} objects reflecting all the + * public methods of the class or interface represented by this {@code + * Class} object, including those declared by the class or interface and + * those inherited from superclasses and superinterfaces. * - *

    The class initialization method {@code } is not - * included in the returned array. If the class declares multiple public - * member methods with the same parameter types, they are all included in - * the returned array. + *

    If this {@code Class} object represents a type that has multiple + * public methods with the same name and parameter types, but different + * return types, then the returned array has a {@code Method} object for + * each such method. * - *

    See The Java Language Specification, sections 8.2 and 8.4. + *

    If this {@code Class} object represents a type with a class + * initialization method {@code }, then the returned array does + * not have a corresponding {@code Method} object. + * + *

    If this {@code Class} object represents an array type, then the + * returned array has a {@code Method} object for each of the public + * methods inherited by the array type from {@code Object}. It does not + * contain a {@code Method} object for {@code clone()}. + * + *

    If this {@code Class} object represents a class or interface with no + * public methods, then the returned array has length 0. + * + *

    If this {@code Class} object represents a primitive type or void, + * then the returned array has length 0. + * + *

    The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Method} objects representing the * public methods of this class @@ -1549,6 +1567,8 @@ public final class Class implements java.io.Serializable, * s.checkPackageAccess()} denies access to the package * of this class. * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive @@ -1595,13 +1615,14 @@ public final class Class implements java.io.Serializable, /** - * Returns a {@code Field} object that reflects the specified public - * member field of the class or interface represented by this - * {@code Class} object. The {@code name} parameter is a - * {@code String} specifying the simple name of the desired field. + * Returns a {@code Field} object that reflects the specified public member + * field of the class or interface represented by this {@code Class} + * object. The {@code name} parameter is a {@code String} specifying the + * simple name of the desired field. * *

    The field to be reflected is determined by the algorithm that - * follows. Let C be the class represented by this object: + * follows. Let C be the class or interface represented by this object: + * *

      *
    1. If C declares a public field with the name specified, that is the * field to be reflected.
    2. @@ -1614,7 +1635,8 @@ public final class Class implements java.io.Serializable, * is thrown. *
    * - *

    See The Java Language Specification, sections 8.2 and 8.3. + *

    If this {@code Class} object represents an array type, then this + * method does not find the {@code length} field of the array type. * * @param name the field name * @return the {@code Field} object of this class specified by @@ -1631,6 +1653,8 @@ public final class Class implements java.io.Serializable, * of this class. * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field getField(String name) @@ -1685,7 +1709,8 @@ public final class Class implements java.io.Serializable, * method and the method being overridden would have the same * signature but different return types. * - *

    See The Java Language Specification, sections 8.2 and 8.4. + *

    If this {@code Class} object represents an array type, then this + * method does not find the {@code clone()} method. * * @param name the name of the method * @param parameterTypes the list of parameters @@ -1702,6 +1727,8 @@ public final class Class implements java.io.Serializable, * s.checkPackageAccess()} denies access to the package * of this class. * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive @@ -1800,12 +1827,15 @@ public final class Class implements java.io.Serializable, * declared by the class or interface represented by this * {@code Class} object. This includes public, protected, default * (package) access, and private fields, but excludes inherited fields. - * The elements in the array returned are not sorted and are not in any - * particular order. This method returns an array of length 0 if the class - * or interface declares no fields, or if this {@code Class} object - * represents a primitive type, an array class, or void. * - *

    See The Java Language Specification, sections 8.2 and 8.3. + *

    If this {@code Class} object represents a class or interface with no + * declared fields, then this method returns an array of length 0. + * + *

    If this {@code Class} object represents an array type, a primitive + * type, or void, then this method returns an array of length 0. + * + *

    The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Field} objects representing all the * declared fields of this class @@ -1831,6 +1861,8 @@ public final class Class implements java.io.Serializable, * * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field[] getDeclaredFields() throws SecurityException { @@ -1840,20 +1872,29 @@ public final class Class implements java.io.Serializable, /** - * Returns an array of {@code Method} objects reflecting all the - * methods declared by the class or interface represented by this - * {@code Class} object. This includes public, protected, default - * (package) access, and private methods, but excludes inherited methods. - * The elements in the array returned are not sorted and are not in any - * particular order. This method returns an array of length 0 if the class - * or interface declares no methods, or if this {@code Class} object - * represents a primitive type, an array class, or void. The class - * initialization method {@code } is not included in the - * returned array. If the class declares multiple public member methods - * with the same parameter types, they are all included in the returned - * array. * - *

    See The Java Language Specification, section 8.2. + * Returns an array containing {@code Method} objects reflecting all the + * declared methods of the class or interface represented by this {@code + * Class} object, including public, protected, default (package) + * access, and private methods, but excluding inherited methods. + * + *

    If this {@code Class} object represents a type that has multiple + * declared methods with the same name and parameter types, but different + * return types, then the returned array has a {@code Method} object for + * each such method. + * + *

    If this {@code Class} object represents a type that has a class + * initialization method {@code }, then the returned array does + * not have a corresponding {@code Method} object. + * + *

    If this {@code Class} object represents a class or interface with no + * declared methods, then the returned array has length 0. + * + *

    If this {@code Class} object represents an array type, a primitive + * type, or void, then the returned array has length 0. + * + *

    The elements in the returned array are not sorted and are not in any + * particular order. * * @return the array of {@code Method} objects representing all the * declared methods of this class @@ -1878,6 +1919,8 @@ public final class Class implements java.io.Serializable, * * * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive @@ -1935,9 +1978,11 @@ public final class Class implements java.io.Serializable, /** * Returns a {@code Field} object that reflects the specified declared * field of the class or interface represented by this {@code Class} - * object. The {@code name} parameter is a {@code String} that - * specifies the simple name of the desired field. Note that this method - * will not reflect the {@code length} field of an array class. + * object. The {@code name} parameter is a {@code String} that specifies + * the simple name of the desired field. + * + *

    If this {@code Class} object represents an array type, then this + * method does not find the {@code length} field of the array type. * * @param name the name of the field * @return the {@code Field} object for the specified field in this @@ -1967,6 +2012,8 @@ public final class Class implements java.io.Serializable, * * * @since JDK1.1 + * @jls 8.2 Class Members + * @jls 8.3 Field Declarations */ @CallerSensitive public Field getDeclaredField(String name) @@ -1994,6 +2041,9 @@ public final class Class implements java.io.Serializable, * name is "<init>"or "<clinit>" a {@code NoSuchMethodException} * is raised. * + *

    If this {@code Class} object represents an array type, then this + * method does not find the {@code clone()} method. + * * @param name the name of the method * @param parameterTypes the parameter array * @return the {@code Method} object for the method of this class @@ -2021,6 +2071,8 @@ public final class Class implements java.io.Serializable, * * * + * @jls 8.2 Class Members + * @jls 8.4 Method Declarations * @since JDK1.1 */ @CallerSensitive diff --git a/jdk/src/share/classes/java/lang/Math.java b/jdk/src/share/classes/java/lang/Math.java index ae83e4265ad..98e901ac942 100644 --- a/jdk/src/share/classes/java/lang/Math.java +++ b/jdk/src/share/classes/java/lang/Math.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -646,7 +646,7 @@ public final class Math { /** * Returns the closest {@code int} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

    * Special cases: @@ -665,15 +665,37 @@ public final class Math { * @see java.lang.Integer#MIN_VALUE */ public static int round(float a) { - if (a != 0x1.fffffep-2f) // greatest float value less than 0.5 - return (int)floor(a + 0.5f); - else - return 0; + int intBits = Float.floatToRawIntBits(a); + int biasedExp = (intBits & FloatConsts.EXP_BIT_MASK) + >> (FloatConsts.SIGNIFICAND_WIDTH - 1); + int shift = (FloatConsts.SIGNIFICAND_WIDTH - 2 + + FloatConsts.EXP_BIAS) - biasedExp; + if ((shift & -32) == 0) { // shift >= 0 && shift < 32 + // a is a finite number such that pow(2,-32) <= ulp(a) < 1 + int r = ((intBits & FloatConsts.SIGNIF_BIT_MASK) + | (FloatConsts.SIGNIF_BIT_MASK + 1)); + if (intBits < 0) { + r = -r; + } + // In the comments below each Java expression evaluates to the value + // the corresponding mathematical expression: + // (r) evaluates to a / ulp(a) + // (r >> shift) evaluates to floor(a * 2) + // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2) + // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2) + return ((r >> shift) + 1) >> 1; + } else { + // a is either + // - a finite number with abs(a) < exp(2,FloatConsts.SIGNIFICAND_WIDTH-32) < 1/2 + // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer + // - an infinity or NaN + return (int) a; + } } /** * Returns the closest {@code long} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

    Special cases: *

    • If the argument is NaN, the result is 0. @@ -692,10 +714,32 @@ public final class Math { * @see java.lang.Long#MIN_VALUE */ public static long round(double a) { - if (a != 0x1.fffffffffffffp-2) // greatest double value less than 0.5 - return (long)floor(a + 0.5d); - else - return 0; + long longBits = Double.doubleToRawLongBits(a); + long biasedExp = (longBits & DoubleConsts.EXP_BIT_MASK) + >> (DoubleConsts.SIGNIFICAND_WIDTH - 1); + long shift = (DoubleConsts.SIGNIFICAND_WIDTH - 2 + + DoubleConsts.EXP_BIAS) - biasedExp; + if ((shift & -64) == 0) { // shift >= 0 && shift < 64 + // a is a finite number such that pow(2,-64) <= ulp(a) < 1 + long r = ((longBits & DoubleConsts.SIGNIF_BIT_MASK) + | (DoubleConsts.SIGNIF_BIT_MASK + 1)); + if (longBits < 0) { + r = -r; + } + // In the comments below each Java expression evaluates to the value + // the corresponding mathematical expression: + // (r) evaluates to a / ulp(a) + // (r >> shift) evaluates to floor(a * 2) + // ((r >> shift) + 1) evaluates to floor((a + 1/2) * 2) + // (((r >> shift) + 1) >> 1) evaluates to floor(a + 1/2) + return ((r >> shift) + 1) >> 1; + } else { + // a is either + // - a finite number with abs(a) < exp(2,DoubleConsts.SIGNIFICAND_WIDTH-64) < 1/2 + // - a finite number with ulp(a) >= 1 and hence a is a mathematical integer + // - an infinity or NaN + return (long) a; + } } private static final class RandomNumberGeneratorHolder { diff --git a/jdk/src/share/classes/java/lang/SecurityManager.java b/jdk/src/share/classes/java/lang/SecurityManager.java index 34be905bd02..3565082033c 100644 --- a/jdk/src/share/classes/java/lang/SecurityManager.java +++ b/jdk/src/share/classes/java/lang/SecurityManager.java @@ -1336,9 +1336,16 @@ class SecurityManager { * top-level windows; false otherwise. * @exception NullPointerException if the window argument is * null. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see java.awt.Window * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public boolean checkTopLevelWindow(Object window) { if (window == null) { throw new NullPointerException("window can't be null"); @@ -1398,8 +1405,15 @@ class SecurityManager { * @since JDK1.1 * @exception SecurityException if the calling thread does not have * permission to access the system clipboard. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public void checkSystemClipboardAccess() { Permission perm = SecurityConstants.AWT.ACCESS_CLIPBOARD_PERMISSION; if (perm == null) { @@ -1427,8 +1441,15 @@ class SecurityManager { * @since JDK1.1 * @exception SecurityException if the calling thread does not have * permission to access the AWT event queue. + * @deprecated The dependency on {@code AWTPermission} creates an + * impediment to future modularization of the Java platform. + * Users of this method should instead invoke + * {@link #checkPermission} directly. + * This method will be changed in a future release to check + * the permission {@code java.security.AllPermission}. * @see #checkPermission(java.security.Permission) checkPermission */ + @Deprecated public void checkAwtEventQueueAccess() { Permission perm = SecurityConstants.AWT.CHECK_AWT_EVENTQUEUE_PERMISSION; if (perm == null) { diff --git a/jdk/src/share/classes/java/lang/StrictMath.java b/jdk/src/share/classes/java/lang/StrictMath.java index 52336484e75..ae4af2bcac8 100644 --- a/jdk/src/share/classes/java/lang/StrictMath.java +++ b/jdk/src/share/classes/java/lang/StrictMath.java @@ -633,7 +633,7 @@ public final class StrictMath { /** * Returns the closest {@code int} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

      Special cases: *

      • If the argument is NaN, the result is 0. @@ -656,7 +656,7 @@ public final class StrictMath { /** * Returns the closest {@code long} to the argument, with ties - * rounding up. + * rounding to positive infinity. * *

        Special cases: *

        • If the argument is NaN, the result is 0. diff --git a/jdk/src/share/classes/java/lang/String.java b/jdk/src/share/classes/java/lang/String.java index 651a85017ed..2231aa3bb71 100644 --- a/jdk/src/share/classes/java/lang/String.java +++ b/jdk/src/share/classes/java/lang/String.java @@ -2457,8 +2457,8 @@ public final class String * String message = String.join(" ", strings); * //message returned is: "Java is cool" * - * Set strings = new HashSet<>(); - * Strings.add("Java"); strings.add("is"); + * Set strings = new LinkedHashSet<>(); + * strings.add("Java"); strings.add("is"); * strings.add("very"); strings.add("cool"); * String message = String.join("-", strings); * //message returned is: "Java-is-very-cool" @@ -2652,7 +2652,7 @@ public final class String * returns {@code "t\u005Cu0131tle"}, where '\u005Cu0131' is the * LATIN SMALL LETTER DOTLESS I character. * To obtain correct results for locale insensitive strings, use - * {@code toLowerCase(Locale.ENGLISH)}. + * {@code toLowerCase(Locale.ROOT)}. *

          * @return the {@code String}, converted to lowercase. * @see java.lang.String#toLowerCase(Locale) @@ -2815,7 +2815,7 @@ public final class String * returns {@code "T\u005Cu0130TLE"}, where '\u005Cu0130' is the * LATIN CAPITAL LETTER I WITH DOT ABOVE character. * To obtain correct results for locale insensitive strings, use - * {@code toUpperCase(Locale.ENGLISH)}. + * {@code toUpperCase(Locale.ROOT)}. *

          * @return the {@code String}, converted to uppercase. * @see java.lang.String#toUpperCase(Locale) diff --git a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java index 79b3b69fcf3..92a44a048f3 100644 --- a/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java +++ b/jdk/src/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java @@ -124,7 +124,7 @@ import static sun.invoke.util.Wrapper.isWrapperType; this.samMethodType = samMethodType; this.implMethod = implMethod; - this.implInfo = new MethodHandleInfo(implMethod); + this.implInfo = caller.revealDirect(implMethod); // @@@ Temporary work-around pending resolution of 8005119 this.implKind = (implInfo.getReferenceKind() == MethodHandleInfo.REF_invokeSpecial) ? MethodHandleInfo.REF_invokeVirtual diff --git a/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java b/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java new file mode 100644 index 00000000000..0ecd005a8d3 --- /dev/null +++ b/jdk/src/share/classes/java/lang/invoke/InfoFromMemberName.java @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.lang.invoke; + +import java.security.*; +import java.lang.reflect.*; +import java.lang.invoke.MethodHandleNatives.Constants; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandleStatics.*; + +/* + * Auxiliary to MethodHandleInfo, wants to nest in MethodHandleInfo but must be non-public. + */ +/*non-public*/ +final +class InfoFromMemberName implements MethodHandleInfo { + private final MemberName member; + private final int referenceKind; + + InfoFromMemberName(Lookup lookup, MemberName member, byte referenceKind) { + assert(member.isResolved() || member.isMethodHandleInvoke()); + assert(member.referenceKindIsConsistentWith(referenceKind)); + this.member = member; + this.referenceKind = referenceKind; + } + + @Override + public Class getDeclaringClass() { + return member.getDeclaringClass(); + } + + @Override + public String getName() { + return member.getName(); + } + + @Override + public MethodType getMethodType() { + return member.getMethodOrFieldType(); + } + + @Override + public int getModifiers() { + return member.getModifiers(); + } + + @Override + public int getReferenceKind() { + return referenceKind; + } + + @Override + public String toString() { + return MethodHandleInfo.toString(getReferenceKind(), getDeclaringClass(), getName(), getMethodType()); + } + + @Override + public T reflectAs(Class expected, Lookup lookup) { + if (member.isMethodHandleInvoke() && !member.isVarargs()) { + // This member is an instance of a signature-polymorphic method, which cannot be reflected + // A method handle invoker can come in either of two forms: + // A generic placeholder (present in the source code, and varargs) + // and a signature-polymorphic instance (synthetic and not varargs). + // For more information see comments on {@link MethodHandleNatives#linkMethod}. + throw new IllegalArgumentException("cannot reflect signature polymorphic method"); + } + Member mem = AccessController.doPrivileged(new PrivilegedAction() { + public Member run() { + try { + return reflectUnchecked(); + } catch (ReflectiveOperationException ex) { + throw new IllegalArgumentException(ex); + } + } + }); + try { + Class defc = getDeclaringClass(); + byte refKind = (byte) getReferenceKind(); + lookup.checkAccess(refKind, defc, convertToMemberName(refKind, mem)); + } catch (IllegalAccessException ex) { + throw new IllegalArgumentException(ex); + } + return expected.cast(mem); + } + + private Member reflectUnchecked() throws ReflectiveOperationException { + byte refKind = (byte) getReferenceKind(); + Class defc = getDeclaringClass(); + boolean isPublic = Modifier.isPublic(getModifiers()); + if (MethodHandleNatives.refKindIsMethod(refKind)) { + if (isPublic) + return defc.getMethod(getName(), getMethodType().parameterArray()); + else + return defc.getDeclaredMethod(getName(), getMethodType().parameterArray()); + } else if (MethodHandleNatives.refKindIsConstructor(refKind)) { + if (isPublic) + return defc.getConstructor(getMethodType().parameterArray()); + else + return defc.getDeclaredConstructor(getMethodType().parameterArray()); + } else if (MethodHandleNatives.refKindIsField(refKind)) { + if (isPublic) + return defc.getField(getName()); + else + return defc.getDeclaredField(getName()); + } else { + throw new IllegalArgumentException("referenceKind="+refKind); + } + } + + private static MemberName convertToMemberName(byte refKind, Member mem) throws IllegalAccessException { + if (mem instanceof Method) { + boolean wantSpecial = (refKind == REF_invokeSpecial); + return new MemberName((Method) mem, wantSpecial); + } else if (mem instanceof Constructor) { + return new MemberName((Constructor) mem); + } else if (mem instanceof Field) { + boolean isSetter = (refKind == REF_putField || refKind == REF_putStatic); + return new MemberName((Field) mem, isSetter); + } + throw new InternalError(mem.getClass().getName()); + } +} diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 3ddf5d4c1c5..6228c07b7b0 100644 --- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -612,6 +612,12 @@ class InvokerBytecodeGenerator { return false; // inner class of some sort if (cls.getClassLoader() != MethodHandle.class.getClassLoader()) return false; // not on BCP + MethodType mtype = member.getMethodOrFieldType(); + if (!isStaticallyNameable(mtype.returnType())) + return false; + for (Class ptype : mtype.parameterArray()) + if (!isStaticallyNameable(ptype)) + return false; if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls)) return true; // in java.lang.invoke package if (member.isPublic() && isStaticallyNameable(cls)) diff --git a/jdk/src/share/classes/java/lang/invoke/Invokers.java b/jdk/src/share/classes/java/lang/invoke/Invokers.java index 8d8e019d722..0ef6078b6b5 100644 --- a/jdk/src/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java @@ -87,6 +87,7 @@ class Invokers { lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER); invoker = SimpleMethodHandle.make(invokerType, lform); } + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invokeExact", mtype)); assert(checkInvoker(invoker)); exactInvoker = invoker; return invoker; @@ -110,6 +111,7 @@ class Invokers { lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER); invoker = SimpleMethodHandle.make(invokerType, lform); } + invoker = invoker.withInternalMemberName(MemberName.makeMethodHandleInvoke("invoke", mtype)); assert(checkInvoker(invoker)); generalInvoker = invoker; return invoker; diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java index dfb468417d6..910574befe7 100644 --- a/jdk/src/share/classes/java/lang/invoke/MemberName.java +++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java @@ -320,14 +320,18 @@ import java.util.Objects; /** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */ public boolean isMethodHandleInvoke() { - final int bits = Modifier.NATIVE | Modifier.FINAL; + final int bits = MH_INVOKE_MODS; final int negs = Modifier.STATIC; if (testFlags(bits | negs, bits) && clazz == MethodHandle.class) { - return name.equals("invoke") || name.equals("invokeExact"); + return isMethodHandleInvokeName(name); } return false; } + public static boolean isMethodHandleInvokeName(String name) { + return name.equals("invoke") || name.equals("invokeExact"); + } + private static final int MH_INVOKE_MODS = Modifier.NATIVE | Modifier.FINAL | Modifier.PUBLIC; /** Utility method to query the modifier flags of this member. */ public boolean isStatic() { @@ -482,12 +486,27 @@ import java.util.Objects; m.getClass(); // NPE check // fill in vmtarget, vmindex while we have m in hand: MethodHandleNatives.init(this, m); + if (clazz == null) { // MHN.init failed + if (m.getDeclaringClass() == MethodHandle.class && + isMethodHandleInvokeName(m.getName())) { + // The JVM did not reify this signature-polymorphic instance. + // Need a special case here. + // See comments on MethodHandleNatives.linkMethod. + MethodType type = MethodType.methodType(m.getReturnType(), m.getParameterTypes()); + int flags = flagsMods(IS_METHOD, m.getModifiers(), REF_invokeVirtual); + init(MethodHandle.class, m.getName(), type, flags); + if (isMethodHandleInvoke()) + return; + } + throw new LinkageError(m.toString()); + } assert(isResolved() && this.clazz != null); this.name = m.getName(); if (this.type == null) this.type = new Object[] { m.getReturnType(), m.getParameterTypes() }; if (wantSpecial) { - assert(!isAbstract()) : this; + if (isAbstract()) + throw new AbstractMethodError(this.toString()); if (getReferenceKind() == REF_invokeVirtual) changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual); else if (getReferenceKind() == REF_invokeInterface) @@ -562,6 +581,22 @@ import java.util.Objects; initResolved(true); } + /** + * Create a name for a signature-polymorphic invoker. + * This is a placeholder for a signature-polymorphic instance + * (of MH.invokeExact, etc.) that the JVM does not reify. + * See comments on {@link MethodHandleNatives#linkMethod}. + */ + static MemberName makeMethodHandleInvoke(String name, MethodType type) { + return makeMethodHandleInvoke(name, type, MH_INVOKE_MODS | SYNTHETIC); + } + static MemberName makeMethodHandleInvoke(String name, MethodType type, int mods) { + MemberName mem = new MemberName(MethodHandle.class, name, type, REF_invokeVirtual); + mem.flags |= mods; // it's not resolved, but add these modifiers anyway + assert(mem.isMethodHandleInvoke()) : mem; + return mem; + } + // bare-bones constructor; the JVM will fill it in MemberName() { } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java index df784d35e5b..613d223fe2a 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java @@ -1284,6 +1284,21 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); return null; // DMH returns DMH.member } + /*non-public*/ + MethodHandle withInternalMemberName(MemberName member) { + if (member != null) { + return MethodHandleImpl.makeWrappedMember(this, member); + } else if (internalMemberName() == null) { + // The required internaMemberName is null, and this MH (like most) doesn't have one. + return this; + } else { + // The following case is rare. Mask the internalMemberName by wrapping the MH in a BMH. + MethodHandle result = rebind(); + assert (result.internalMemberName() == null); + return result; + } + } + /*non-public*/ boolean isInvokeSpecial() { return false; // DMH.Special returns true @@ -1356,7 +1371,7 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); MethodHandle rebind() { // Bind 'this' into a new invoker, of the known class BMH. MethodType type2 = type(); - LambdaForm form2 = reinvokerForm(type2.basicType()); + LambdaForm form2 = reinvokerForm(this); // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) } return BoundMethodHandle.bindSingle(type2, form2, this); } @@ -1369,23 +1384,38 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString()); /** Create a LF which simply reinvokes a target of the given basic type. * The target MH must override {@link #reinvokerTarget} to provide the target. */ - static LambdaForm reinvokerForm(MethodType mtype) { - mtype = mtype.basicType(); + static LambdaForm reinvokerForm(MethodHandle target) { + MethodType mtype = target.type().basicType(); LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE); if (reinvoker != null) return reinvoker; - MethodHandle MH_invokeBasic = MethodHandles.basicInvoker(mtype); + if (mtype.parameterSlotCount() >= MethodType.MAX_MH_ARITY) + return makeReinvokerForm(target.type(), target); // cannot cache this + reinvoker = makeReinvokerForm(mtype, null); + return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, reinvoker); + } + private static LambdaForm makeReinvokerForm(MethodType mtype, MethodHandle customTargetOrNull) { + boolean customized = (customTargetOrNull != null); + MethodHandle MH_invokeBasic = customized ? null : MethodHandles.basicInvoker(mtype); final int THIS_BMH = 0; final int ARG_BASE = 1; final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); int nameCursor = ARG_LIMIT; - final int NEXT_MH = nameCursor++; + final int NEXT_MH = customized ? -1 : nameCursor++; final int REINVOKE = nameCursor++; LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType()); - names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); - Object[] targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); - targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH - names[REINVOKE] = new LambdaForm.Name(MH_invokeBasic, targetArgs); - return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, new LambdaForm("BMH.reinvoke", ARG_LIMIT, names)); + Object[] targetArgs; + MethodHandle targetMH; + if (customized) { + targetArgs = Arrays.copyOfRange(names, ARG_BASE, ARG_LIMIT, Object[].class); + targetMH = customTargetOrNull; + } else { + names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]); + targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class); + targetArgs[0] = names[NEXT_MH]; // overwrite this MH with next MH + targetMH = MethodHandles.basicInvoker(mtype); + } + names[REINVOKE] = new LambdaForm.Name(targetMH, targetArgs); + return new LambdaForm("BMH.reinvoke", ARG_LIMIT, names); } private static final LambdaForm.NamedFunction NF_reinvokerTarget; diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java index 04eda964966..5ab7f7adb7b 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -317,7 +317,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; private MethodHandle cache; AsVarargsCollector(MethodHandle target, MethodType type, Class arrayType) { - super(type, reinvokerForm(type)); + super(type, reinvokerForm(target)); this.target = target; this.arrayType = arrayType; this.cache = target.asCollector(arrayType, 0); @@ -778,16 +778,27 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } static Empty throwException(T t) throws T { throw t; } - static MethodHandle FAKE_METHOD_HANDLE_INVOKE; - static - MethodHandle fakeMethodHandleInvoke(MemberName method) { - MethodType type = method.getInvocationType(); - assert(type.equals(MethodType.methodType(Object.class, Object[].class))); - MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE; + static MethodHandle[] FAKE_METHOD_HANDLE_INVOKE = new MethodHandle[2]; + static MethodHandle fakeMethodHandleInvoke(MemberName method) { + int idx; + assert(method.isMethodHandleInvoke()); + switch (method.getName()) { + case "invoke": idx = 0; break; + case "invokeExact": idx = 1; break; + default: throw new InternalError(method.getName()); + } + MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE[idx]; if (mh != null) return mh; - mh = throwException(type.insertParameterTypes(0, UnsupportedOperationException.class)); + MethodType type = MethodType.methodType(Object.class, UnsupportedOperationException.class, + MethodHandle.class, Object[].class); + mh = throwException(type); mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle")); - FAKE_METHOD_HANDLE_INVOKE = mh; + if (!method.getInvocationType().equals(mh.type())) + throw new InternalError(method.toString()); + mh = mh.withInternalMemberName(method); + mh = mh.asVarargsCollector(Object[].class); + assert(method.isVarargs()); + FAKE_METHOD_HANDLE_INVOKE[idx] = mh; return mh; } @@ -821,7 +832,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; MethodHandle vamh = prepareForInvoker(mh); // Cache the result of makeInjectedInvoker once per argument class. MethodHandle bccInvoker = CV_makeInjectedInvoker.get(hostClass); - return restoreToType(bccInvoker.bindTo(vamh), mh.type()); + return restoreToType(bccInvoker.bindTo(vamh), mh.type(), mh.internalMemberName()); } private static MethodHandle makeInjectedInvoker(Class hostClass) { @@ -876,8 +887,11 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } // Undo the adapter effect of prepareForInvoker: - private static MethodHandle restoreToType(MethodHandle vamh, MethodType type) { - return vamh.asCollector(Object[].class, type.parameterCount()).asType(type); + private static MethodHandle restoreToType(MethodHandle vamh, MethodType type, MemberName member) { + MethodHandle mh = vamh.asCollector(Object[].class, type.parameterCount()); + mh = mh.asType(type); + mh = mh.withInternalMemberName(member); + return mh; } private static final MethodHandle MH_checkCallerClass; @@ -939,4 +953,41 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; } } } + + + /** This subclass allows a wrapped method handle to be re-associated with an arbitrary member name. */ + static class WrappedMember extends MethodHandle { + private final MethodHandle target; + private final MemberName member; + + private WrappedMember(MethodHandle target, MethodType type, MemberName member) { + super(type, reinvokerForm(target)); + this.target = target; + this.member = member; + } + + @Override + MethodHandle reinvokerTarget() { + return target; + } + @Override + MemberName internalMemberName() { + return member; + } + @Override + boolean isInvokeSpecial() { + return target.isInvokeSpecial(); + } + @Override + MethodHandle viewAsType(MethodType newType) { + return new WrappedMember(target, newType, member); + } + } + + static MethodHandle makeWrappedMember(MethodHandle target, MemberName member) { + if (member.equals(target.internalMemberName())) + return target; + return new WrappedMember(target, target.type(), member); + } + } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java index 380ca59b6e1..72fd8e91035 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java @@ -24,80 +24,246 @@ */ package java.lang.invoke; + +import java.lang.reflect.*; +import java.util.*; import java.lang.invoke.MethodHandleNatives.Constants; +import java.lang.invoke.MethodHandles.Lookup; +import static java.lang.invoke.MethodHandleStatics.*; /** - * Cracking (reflecting) method handles back into their constituent symbolic parts. + * A symbolic reference obtained by cracking a method handle into its consitutent symbolic parts. + * To crack a direct method handle, call {@link Lookup#revealDirect Lookup.revealDirect}. + *

          + * A direct method handle represents a method, constructor, or field without + * any intervening argument bindings or other transformations. + * The method, constructor, or field referred to by a direct method handle is called + * its underlying member. + * Direct method handles may be obtained in any of these ways: + *

            + *
          • By executing an {@code ldc} instruction on a {@code CONSTANT_MethodHandle} constant. + * (See the Java Virtual Machine Specification, sections 4.4.8 and 5.4.3.) + *
          • By calling one of the Lookup Factory Methods, + * such as {@link Lookup#findVirtual Lookup.findVirtual}, + * to resolve a symbolic reference into a method handle. + * A symbolic reference consists of a class, name string, and type. + *
          • By calling the factory method {@link Lookup#unreflect Lookup.unreflect} + * or {@link Lookup#unreflectSpecial Lookup.unreflectSpecial} + * to convert a {@link Method} into a method handle. + *
          • By calling the factory method {@link Lookup#unreflectConstructor Lookup.unreflectConstructor} + * to convert a {@link Constructor} into a method handle. + *
          • By calling the factory method {@link Lookup#unreflectGetter Lookup.unreflectGetter} + * or {@link Lookup#unreflectSetter Lookup.unreflectSetter} + * to convert a {@link Field} into a method handle. + *
          + * In all of these cases, it is possible to crack the resulting direct method handle + * to recover a symbolic reference for the underlying method, constructor, or field. + * Cracking must be done via a {@code Lookup} object equivalent to that which created + * the target method handle, or which has enough access permissions to recreate + * an equivalent method handle. * + *

          Reference kinds

          + * The Lookup Factory Methods + * correspond to all major use cases for methods, constructors, and fields. + * These use cases may be distinguished using small integers as follows: + *
    Option NameDescription
    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    reference kinddescriptive namescopememberbehavior
    {@code 1}{@code REF_getField}{@code class}{@code FT f;}{@code (T) this.f;}
    {@code 2}{@code REF_getStatic}{@code class} or {@code interface}{@code static}
    {@code FT f;}
    {@code (T) C.f;}
    {@code 3}{@code REF_putField}{@code class}{@code FT f;}{@code this.f = x;}
    {@code 4}{@code REF_putStatic}{@code class}{@code static}
    {@code FT f;}
    {@code C.f = arg;}
    {@code 5}{@code REF_invokeVirtual}{@code class}{@code T m(A*);}{@code (T) this.m(arg*);}
    {@code 6}{@code REF_invokeStatic}{@code class} or {@code interface}{@code static}
    {@code T m(A*);}
    {@code (T) C.m(arg*);}
    {@code 7}{@code REF_invokeSpecial}{@code class} or {@code interface}{@code T m(A*);}{@code (T) super.m(arg*);}
    {@code 8}{@code REF_newInvokeSpecial}{@code class}{@code C(A*);}{@code new C(arg*);}
    {@code 9}{@code REF_invokeInterface}{@code interface}{@code T m(A*);}{@code (T) this.m(arg*);}
    + * @since 1.8 */ -final class MethodHandleInfo { - public static final int - REF_getField = Constants.REF_getField, - REF_getStatic = Constants.REF_getStatic, - REF_putField = Constants.REF_putField, - REF_putStatic = Constants.REF_putStatic, - REF_invokeVirtual = Constants.REF_invokeVirtual, - REF_invokeStatic = Constants.REF_invokeStatic, - REF_invokeSpecial = Constants.REF_invokeSpecial, - REF_newInvokeSpecial = Constants.REF_newInvokeSpecial, - REF_invokeInterface = Constants.REF_invokeInterface; +public +interface MethodHandleInfo { + /** + * A direct method handle reference kind, + * as defined in the table above. + */ + public static final int + REF_getField = Constants.REF_getField, + REF_getStatic = Constants.REF_getStatic, + REF_putField = Constants.REF_putField, + REF_putStatic = Constants.REF_putStatic, + REF_invokeVirtual = Constants.REF_invokeVirtual, + REF_invokeStatic = Constants.REF_invokeStatic, + REF_invokeSpecial = Constants.REF_invokeSpecial, + REF_newInvokeSpecial = Constants.REF_newInvokeSpecial, + REF_invokeInterface = Constants.REF_invokeInterface; - private final Class declaringClass; - private final String name; - private final MethodType methodType; - private final int referenceKind; + /** + * Returns the reference kind of the cracked method handle, which in turn + * determines whether the method handle's underlying member was a constructor, method, or field. + * See the table above for definitions. + * @return the integer code for the kind of reference used to access the underlying member + */ + public int getReferenceKind(); - public MethodHandleInfo(MethodHandle mh) { - MemberName mn = mh.internalMemberName(); - if (mn == null) throw new IllegalArgumentException("not a direct method handle"); - this.declaringClass = mn.getDeclaringClass(); - this.name = mn.getName(); - this.methodType = mn.getMethodOrFieldType(); - byte refKind = mn.getReferenceKind(); - if (refKind == REF_invokeSpecial && !mh.isInvokeSpecial()) - // Devirtualized method invocation is usually formally virtual. - refKind = REF_invokeVirtual; - this.referenceKind = refKind; - } + /** + * Returns the class in which the cracked method handle's underlying member was defined. + * @return the declaring class of the underlying member + */ + public Class getDeclaringClass(); - public Class getDeclaringClass() { - return declaringClass; - } + /** + * Returns the name of the cracked method handle's underlying member. + * This is {@code "<init>"} if the underlying member was a constructor, + * else it is a simple method name or field name. + * @return the simple name of the underlying member + */ + public String getName(); - public String getName() { - return name; - } + /** + * Returns the nominal type of the cracked symbolic reference, expressed as a method type. + * If the reference is to a constructor, the return type will be {@code void}. + * If it is to a non-static method, the method type will not mention the {@code this} parameter. + * If it is to a field and the requested access is to read the field, + * the method type will have no parameters and return the field type. + * If it is to a field and the requested access is to write the field, + * the method type will have one parameter of the field type and return {@code void}. + *

    + * Note that original direct method handle may include a leading {@code this} parameter, + * or (in the case of a constructor) will replace the {@code void} return type + * with the constructed class. + * The nominal type does not include any {@code this} parameter, + * and (in the case of a constructor) will return {@code void}. + * @return the type of the underlying member, expressed as a method type + */ + public MethodType getMethodType(); - public MethodType getMethodType() { - return methodType; - } + // Utility methods. + // NOTE: class/name/type and reference kind constitute a symbolic reference + // member and modifiers are an add-on, derived from Core Reflection (or the equivalent) - public int getModifiers() { - return -1; //TODO - } + /** + * Reflects the underlying member as a method, constructor, or field object. + * If the underlying member is public, it is reflected as if by + * {@code getMethod}, {@code getConstructor}, or {@code getField}. + * Otherwise, it is reflected as if by + * {@code getDeclaredMethod}, {@code getDeclaredConstructor}, or {@code getDeclaredField}. + * The underlying member must be accessible to the given lookup object. + * @param the desired type of the result, either {@link Member} or a subtype + * @param expected a class object representing the desired result type {@code T} + * @param lookup the lookup object that created this MethodHandleInfo, or one with equivalent access privileges + * @return a reference to the method, constructor, or field object + * @exception ClassCastException if the member is not of the expected type + * @exception NullPointerException if either argument is {@code null} + * @exception IllegalArgumentException if the underlying member is not accessible to the given lookup object + */ + public T reflectAs(Class expected, Lookup lookup); - public int getReferenceKind() { - return referenceKind; - } + /** + * Returns the access modifiers of the underlying member. + * @return the Java language modifiers for underlying member, + * or -1 if the member cannot be accessed + * @see Modifier + * @see reflectAs + */ + public int getModifiers(); - static String getReferenceKindString(int referenceKind) { - switch (referenceKind) { - case REF_getField: return "getfield"; - case REF_getStatic: return "getstatic"; - case REF_putField: return "putfield"; - case REF_putStatic: return "putstatic"; - case REF_invokeVirtual: return "invokevirtual"; - case REF_invokeStatic: return "invokestatic"; - case REF_invokeSpecial: return "invokespecial"; - case REF_newInvokeSpecial: return "newinvokespecial"; - case REF_invokeInterface: return "invokeinterface"; - default: return "UNKNOWN_REFENCE_KIND" + "[" + referenceKind + "]"; - } + /** + * Determines if the underlying member was a variable arity method or constructor. + * Such members are represented by method handles that are varargs collectors. + * @implSpec + * This produces a result equivalent to: + *

    {@code
    +     *     getReferenceKind() >= REF_invokeVirtual && Modifier.isTransient(getModifiers())
    +     * }
    + * + * + * @return {@code true} if and only if the underlying member was declared with variable arity. + */ + // spelling derived from java.lang.reflect.Executable, not MethodHandle.isVarargsCollector + public default boolean isVarArgs() { + // fields are never varargs: + if (MethodHandleNatives.refKindIsField((byte) getReferenceKind())) + return false; + // not in the public API: Modifier.VARARGS + final int ACC_VARARGS = 0x00000080; // from JVMS 4.6 (Table 4.20) + assert(ACC_VARARGS == Modifier.TRANSIENT); + return Modifier.isTransient(getModifiers()); } - @Override - public String toString() { - return String.format("%s %s.%s:%s", getReferenceKindString(referenceKind), - declaringClass.getName(), name, methodType); + /** + * Returns the descriptive name of the given reference kind, + * as defined in the table above. + * The conventional prefix "REF_" is omitted. + * @param referenceKind an integer code for a kind of reference used to access a class member + * @return a mixed-case string such as {@code "getField"} + * @exception IllegalArgumentException if the argument is not a valid + * reference kind number + */ + public static String referenceKindToString(int referenceKind) { + if (!MethodHandleNatives.refKindIsValid(referenceKind)) + throw newIllegalArgumentException("invalid reference kind", referenceKind); + return MethodHandleNatives.refKindName((byte)referenceKind); + } + + /** + * Returns a string representation for a {@code MethodHandleInfo}, + * given the four parts of its symbolic reference. + * This is defined to be of the form {@code "RK C.N:MT"}, where {@code RK} is the + * {@linkplain #referenceKindToString reference kind string} for {@code kind}, + * {@code C} is the {@linkplain java.lang.Class#getName name} of {@code defc} + * {@code N} is the {@code name}, and + * {@code MT} is the {@code type}. + * These four values may be obtained from the + * {@linkplain #getReferenceKind reference kind}, + * {@linkplain #getDeclaringClass declaring class}, + * {@linkplain #getName member name}, + * and {@linkplain #getMethodType method type} + * of a {@code MethodHandleInfo} object. + * + * @implSpec + * This produces a result equivalent to: + *
    {@code
    +     *     String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type)
    +     * }
    + * + * @param kind the {@linkplain #getReferenceKind reference kind} part of the symbolic reference + * @param defc the {@linkplain #getDeclaringClass declaring class} part of the symbolic reference + * @param name the {@linkplain #getName member name} part of the symbolic reference + * @param type the {@linkplain #getMethodType method type} part of the symbolic reference + * @return a string of the form {@code "RK C.N:MT"} + * @exception IllegalArgumentException if the first argument is not a valid + * reference kind number + * @exception NullPointerException if any reference argument is {@code null} + */ + public static String toString(int kind, Class defc, String name, MethodType type) { + Objects.requireNonNull(name); Objects.requireNonNull(type); + return String.format("%s %s.%s:%s", referenceKindToString(kind), defc.getName(), name, type); } } diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java index 06e61a7dd8b..4f83e82158c 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -205,6 +205,9 @@ class MethodHandleNatives { static boolean refKindIsMethod(byte refKind) { return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial); } + static boolean refKindIsConstructor(byte refKind) { + return (refKind == REF_newInvokeSpecial); + } static boolean refKindHasReceiver(byte refKind) { assert(refKindIsValid(refKind)); return (refKind & 1) != 0; @@ -313,7 +316,65 @@ class MethodHandleNatives { * The method assumes the following arguments on the stack: * 0: the method handle being invoked * 1-N: the arguments to the method handle invocation - * N+1: an implicitly added type argument (the given MethodType) + * N+1: an optional, implicitly added argument (typically the given MethodType) + *

    + * The nominal method at such a call site is an instance of + * a signature-polymorphic method (see @PolymorphicSignature). + * Such method instances are user-visible entities which are + * "split" from the generic placeholder method in {@code MethodHandle}. + * (Note that the placeholder method is not identical with any of + * its instances. If invoked reflectively, is guaranteed to throw an + * {@code UnsupportedOperationException}.) + * If the signature-polymorphic method instance is ever reified, + * it appears as a "copy" of the original placeholder + * (a native final member of {@code MethodHandle}) except + * that its type descriptor has shape required by the instance, + * and the method instance is not varargs. + * The method instance is also marked synthetic, since the + * method (by definition) does not appear in Java source code. + *

    + * The JVM is allowed to reify this method as instance metadata. + * For example, {@code invokeBasic} is always reified. + * But the JVM may instead call {@code linkMethod}. + * If the result is an * ordered pair of a {@code (method, appendix)}, + * the method gets all the arguments (0..N inclusive) + * plus the appendix (N+1), and uses the appendix to complete the call. + * In this way, one reusable method (called a "linker method") + * can perform the function of any number of polymorphic instance + * methods. + *

    + * Linker methods are allowed to be weakly typed, with any or + * all references rewritten to {@code Object} and any primitives + * (except {@code long}/{@code float}/{@code double}) + * rewritten to {@code int}. + * A linker method is trusted to return a strongly typed result, + * according to the specific method type descriptor of the + * signature-polymorphic instance it is emulating. + * This can involve (as necessary) a dynamic check using + * data extracted from the appendix argument. + *

    + * The JVM does not inspect the appendix, other than to pass + * it verbatim to the linker method at every call. + * This means that the JDK runtime has wide latitude + * for choosing the shape of each linker method and its + * corresponding appendix. + * Linker methods should be generated from {@code LambdaForm}s + * so that they do not become visible on stack traces. + *

    + * The {@code linkMethod} call is free to omit the appendix + * (returning null) and instead emulate the required function + * completely in the linker method. + * As a corner case, if N==255, no appendix is possible. + * In this case, the method returned must be custom-generated to + * to perform any needed type checking. + *

    + * If the JVM does not reify a method at a call site, but instead + * calls {@code linkMethod}, the corresponding call represented + * in the bytecodes may mention a valid method which is not + * representable with a {@code MemberName}. + * Therefore, use cases for {@code linkMethod} tend to correspond to + * special cases in reflective code such as {@code findVirtual} + * or {@code revealDirect}. */ static MemberName linkMethod(Class callerClass, int refKind, Class defc, String name, Object type, diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java index 78b01215636..f0f9447e001 100644 --- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java @@ -26,8 +26,6 @@ package java.lang.invoke; import java.lang.reflect.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.ArrayList; import java.util.Arrays; @@ -54,6 +52,7 @@ import sun.security.util.SecurityConstants; * *

    * @author John Rose, JSR 292 EG + * @since 1.7 */ public class MethodHandles { @@ -96,6 +95,38 @@ public class MethodHandles { return Lookup.PUBLIC_LOOKUP; } + /** + * Performs an unchecked "crack" of a direct method handle. + * The result is as if the user had obtained a lookup object capable enough + * to crack the target method handle, called + * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect} + * on the target to obtain its symbolic reference, and then called + * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs} + * to resolve the symbolic reference to a member. + *

    + * If there is a security manager, its {@code checkPermission} method + * is called with a {@code ReflectPermission("suppressAccessChecks")} permission. + * @param the desired type of the result, either {@link Member} or a subtype + * @param target a direct method handle to crack into symbolic reference components + * @param expected a class object representing the desired result type {@code T} + * @return a reference to the method, constructor, or field object + * @exception SecurityException if the caller is not privileged to call {@code setAccessible} + * @exception NullPointerException if either argument is {@code null} + * @exception IllegalArgumentException if the target is not a direct method handle + * @exception ClassCastException if the member is not of the expected type + * @since 1.8 + */ + public static T + reflectAs(Class expected, MethodHandle target) { + SecurityManager smgr = System.getSecurityManager(); + if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION); + Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup + return lookup.revealDirect(target).reflectAs(expected, lookup); + } + // Copied from AccessibleObject, as used by Method.setAccessible, etc.: + static final private java.security.Permission ACCESS_PERMISSION = + new ReflectPermission("suppressAccessChecks"); + /** * A lookup object is a factory for creating method handles, * when the creation requires access checking. @@ -647,6 +678,7 @@ public class MethodHandles { return invoker(type); if ("invokeExact".equals(name)) return exactInvoker(type); + assert(!MemberName.isMethodHandleInvokeName(name)); return null; } @@ -892,6 +924,10 @@ return mh1; * @throws NullPointerException if the argument is null */ public MethodHandle unreflect(Method m) throws IllegalAccessException { + if (m.getDeclaringClass() == MethodHandle.class) { + MethodHandle mh = unreflectForMH(m); + if (mh != null) return mh; + } MemberName method = new MemberName(m); byte refKind = method.getReferenceKind(); if (refKind == REF_invokeSpecial) @@ -900,6 +936,12 @@ return mh1; Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method)); } + private MethodHandle unreflectForMH(Method m) { + // these names require special lookups because they throw UnsupportedOperationException + if (MemberName.isMethodHandleInvokeName(m.getName())) + return MethodHandleImpl.fakeMethodHandleInvoke(new MemberName(m)); + return null; + } /** * Produces a method handle for a reflected method. @@ -1004,6 +1046,46 @@ return mh1; return unreflectField(f, true); } + /** + * Cracks a direct method handle created by this lookup object or a similar one. + * Security and access checks are performed to ensure that this lookup object + * is capable of reproducing the target method handle. + * This means that the cracking may fail if target is a direct method handle + * but was created by an unrelated lookup object. + * @param target a direct method handle to crack into symbolic reference components + * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object + * @exception SecurityException if a security manager is present and it + * refuses access + * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails + * @exception NullPointerException if the target is {@code null} + * @since 1.8 + */ + public MethodHandleInfo revealDirect(MethodHandle target) { + MemberName member = target.internalMemberName(); + if (member == null || (!member.isResolved() && !member.isMethodHandleInvoke())) + throw newIllegalArgumentException("not a direct method handle"); + Class defc = member.getDeclaringClass(); + byte refKind = member.getReferenceKind(); + assert(MethodHandleNatives.refKindIsValid(refKind)); + if (refKind == REF_invokeSpecial && !target.isInvokeSpecial()) + // Devirtualized method invocation is usually formally virtual. + // To avoid creating extra MemberName objects for this common case, + // we encode this extra degree of freedom using MH.isInvokeSpecial. + refKind = REF_invokeVirtual; + if (refKind == REF_invokeVirtual && defc.isInterface()) + // Symbolic reference is through interface but resolves to Object method (toString, etc.) + refKind = REF_invokeInterface; + // Check SM permissions and member access before cracking. + try { + checkSecurityManager(defc, member); + checkAccess(refKind, defc, member); + } catch (IllegalAccessException ex) { + throw new IllegalArgumentException(ex); + } + // Produce the handle to the results. + return new InfoFromMemberName(this, member, refKind); + } + /// Helper methods, all package-private. MemberName resolveOrFail(byte refKind, Class refc, String name, Class type) throws NoSuchFieldException, IllegalAccessException { @@ -1201,12 +1283,12 @@ return mh1; private MethodHandle getDirectMethodCommon(byte refKind, Class refc, MemberName method, boolean doRestrict, Class callerClass) throws IllegalAccessException { checkMethod(refKind, refc, method); - if (method.isMethodHandleInvoke()) - return fakeMethodHandleInvoke(method); + assert(!method.isMethodHandleInvoke()); Class refcAsSuper; if (refKind == REF_invokeSpecial && refc != lookupClass() && + !refc.isInterface() && refc != (refcAsSuper = lookupClass().getSuperclass()) && refc.isAssignableFrom(lookupClass())) { assert(!method.getName().equals("")); // not this code path @@ -1234,9 +1316,6 @@ return mh1; mh = restrictReceiver(method, mh, lookupClass()); return mh; } - private MethodHandle fakeMethodHandleInvoke(MemberName method) { - return throwException(method.getReturnType(), UnsupportedOperationException.class); - } private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh, Class callerClass) throws IllegalAccessException { diff --git a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java index a775fc43e34..9be96ff685b 100644 --- a/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java +++ b/jdk/src/share/classes/java/lang/invoke/SerializedLambda.java @@ -225,7 +225,7 @@ public final class SerializedLambda implements Serializable { @Override public String toString() { - String implKind=MethodHandleInfo.getReferenceKindString(implMethodKind); + String implKind=MethodHandleInfo.referenceKindToString(implMethodKind); return String.format("SerializedLambda[%s=%s, %s=%s.%s:%s, " + "%s=%s %s.%s:%s, %s=%s, %s=%d]", "capturingClass", capturingClass, diff --git a/jdk/src/share/classes/java/lang/reflect/Executable.java b/jdk/src/share/classes/java/lang/reflect/Executable.java index aa8820fd2d7..9d41a0217db 100644 --- a/jdk/src/share/classes/java/lang/reflect/Executable.java +++ b/jdk/src/share/classes/java/lang/reflect/Executable.java @@ -428,20 +428,32 @@ public abstract class Executable extends AccessibleObject } /** - * Returns an array of arrays that represent the annotations on - * the formal parameters, in declaration order, of the executable - * represented by this object. (Returns an array of length zero if - * the underlying executable is parameterless. If the executable has - * one or more parameters, a nested array of length zero is - * returned for each parameter with no annotations.) The - * annotation objects contained in the returned arrays are - * serializable. The caller of this method is free to modify the - * returned arrays; it will have no effect on the arrays returned - * to other callers. + * Returns an array of arrays of {@code Annotation}s that + * represent the annotations on the formal parameters, in + * declaration order, of the {@code Executable} represented by + * this object. Synthetic and mandated parameters (see + * explanation below), such as the outer "this" parameter to an + * inner class constructor will be represented in the returned + * array. If the executable has no parameters (meaning no formal, + * no synthetic, and no mandated parameters), a zero-length array + * will be returned. If the {@code Executable} has one or more + * parameters, a nested array of length zero is returned for each + * parameter with no annotations. The annotation objects contained + * in the returned arrays are serializable. The caller of this + * method is free to modify the returned arrays; it will have no + * effect on the arrays returned to other callers. * - * @return an array of arrays that represent the annotations on the formal - * parameters, in declaration order, of the executable represented by this - * object + * A compiler may add extra parameters that are implicitly + * declared in source ("mandated"), as well as parameters that + * are neither implicitly nor explicitly declared in source + * ("synthetic") to the parameter list for a method. See {@link + * java.lang.reflect.Parameter} for more information. + * + * @see java.lang.reflect.Parameter + * @see java.lang.reflect.Parameter#getAnnotations + * @return an array of arrays that represent the annotations on + * the formal and implicit parameters, in declaration order, of + * the executable represented by this object */ public abstract Annotation[][] getParameterAnnotations(); diff --git a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java index be9ac509731..446b4248a8e 100644 --- a/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java +++ b/jdk/src/share/classes/java/net/AbstractPlainSocketImpl.java @@ -719,7 +719,3 @@ abstract class AbstractPlainSocketImpl extends SocketImpl public final static int SHUT_RD = 0; public final static int SHUT_WR = 1; } - -class InetAddressContainer { - InetAddress addr; -} diff --git a/jdk/src/share/classes/java/net/IDN.java b/jdk/src/share/classes/java/net/IDN.java index ed2f3a38159..34642b9824c 100644 --- a/jdk/src/share/classes/java/net/IDN.java +++ b/jdk/src/share/classes/java/net/IDN.java @@ -292,13 +292,17 @@ public final class IDN { if (useSTD3ASCIIRules) { for (int i = 0; i < dest.length(); i++) { int c = dest.charAt(i); - if (!isLDHChar(c)) { - throw new IllegalArgumentException("Contains non-LDH characters"); + if (isNonLDHAsciiCodePoint(c)) { + throw new IllegalArgumentException( + "Contains non-LDH ASCII characters"); } } - if (dest.charAt(0) == '-' || dest.charAt(dest.length() - 1) == '-') { - throw new IllegalArgumentException("Has leading or trailing hyphen"); + if (dest.charAt(0) == '-' || + dest.charAt(dest.length() - 1) == '-') { + + throw new IllegalArgumentException( + "Has leading or trailing hyphen"); } } @@ -401,26 +405,20 @@ public final class IDN { // // LDH stands for "letter/digit/hyphen", with characters restricted to the // 26-letter Latin alphabet , the digits <0-9>, and the hyphen - // <-> - // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x56..0x60, 0x7B..0x7F + // <->. + // Non LDH refers to characters in the ASCII range, but which are not + // letters, digits or the hypen. // - private static boolean isLDHChar(int ch){ - // high runner case - if(ch > 0x007A){ - return false; - } - //['-' '0'..'9' 'A'..'Z' 'a'..'z'] - if((ch == 0x002D) || - (0x0030 <= ch && ch <= 0x0039) || - (0x0041 <= ch && ch <= 0x005A) || - (0x0061 <= ch && ch <= 0x007A) - ){ - return true; - } - return false; + // non-LDH = 0..0x2C, 0x2E..0x2F, 0x3A..0x40, 0x5B..0x60, 0x7B..0x7F + // + private static boolean isNonLDHAsciiCodePoint(int ch){ + return (0x0000 <= ch && ch <= 0x002C) || + (0x002E <= ch && ch <= 0x002F) || + (0x003A <= ch && ch <= 0x0040) || + (0x005B <= ch && ch <= 0x0060) || + (0x007B <= ch && ch <= 0x007F); } - // // search dots in a string and return the index of that character; // or if there is no dots, return the length of input string diff --git a/jdk/src/share/classes/java/net/InetAddressContainer.java b/jdk/src/share/classes/java/net/InetAddressContainer.java new file mode 100644 index 00000000000..28b64022fc7 --- /dev/null +++ b/jdk/src/share/classes/java/net/InetAddressContainer.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.net; + +class InetAddressContainer { + InetAddress addr; +} diff --git a/jdk/src/share/classes/java/nio/file/Files.java b/jdk/src/share/classes/java/nio/file/Files.java index 721184c1533..f084040c179 100644 --- a/jdk/src/share/classes/java/nio/file/Files.java +++ b/jdk/src/share/classes/java/nio/file/Files.java @@ -25,34 +25,56 @@ package java.nio.file; -import java.nio.file.attribute.*; -import java.nio.file.spi.FileSystemProvider; -import java.nio.file.spi.FileTypeDetector; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.UncheckedIOException; +import java.io.Writer; import java.nio.channels.Channels; import java.nio.channels.FileChannel; import java.nio.channels.SeekableByteChannel; -import java.io.Closeable; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.IOException; -import java.io.UncheckedIOException; -import java.util.*; -import java.util.function.BiPredicate; -import java.util.stream.CloseableStream; -import java.util.stream.DelegatingStream; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; +import java.nio.file.attribute.BasicFileAttributeView; +import java.nio.file.attribute.BasicFileAttributes; +import java.nio.file.attribute.DosFileAttributes; +import java.nio.file.attribute.FileAttribute; +import java.nio.file.attribute.FileAttributeView; +import java.nio.file.attribute.FileOwnerAttributeView; +import java.nio.file.attribute.FileStoreAttributeView; +import java.nio.file.attribute.FileTime; +import java.nio.file.attribute.PosixFileAttributeView; +import java.nio.file.attribute.PosixFileAttributes; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.UserPrincipal; +import java.nio.file.spi.FileSystemProvider; +import java.nio.file.spi.FileTypeDetector; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.Spliterator; +import java.util.Spliterators; +import java.util.function.BiPredicate; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; /** * This class consists exclusively of static methods that operate on files, @@ -74,6 +96,21 @@ public final class Files { return path.getFileSystem().provider(); } + /** + * Convert a Closeable to a Runnable by converting checked IOException + * to UncheckedIOException + */ + private static Runnable asUncheckedRunnable(Closeable c) { + return () -> { + try { + c.close(); + } + catch (IOException e) { + throw new UncheckedIOException(e); + } + }; + } + // -- File contents -- /** @@ -3228,29 +3265,7 @@ public final class Files { // -- Stream APIs -- /** - * Implementation of CloseableStream - */ - private static class DelegatingCloseableStream extends DelegatingStream - implements CloseableStream - { - private final Closeable closeable; - - DelegatingCloseableStream(Closeable c, Stream delegate) { - super(delegate); - this.closeable = c; - } - - public void close() { - try { - closeable.close(); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } - } - - /** - * Return a lazily populated {@code CloseableStream}, the elements of + * Return a lazily populated {@code Stream}, the elements of * which are the entries in the directory. The listing is not recursive. * *

    The elements of the stream are {@link Path} objects that are @@ -3264,10 +3279,13 @@ public final class Files { * reflect updates to the directory that occur after returning from this * method. * - *

    When not using the try-with-resources construct, then the stream's - * {@link CloseableStream#close close} method should be invoked after the - * operation is completed so as to free any resources held for the open - * directory. Operating on a closed stream behaves as if the end of stream + *

    The returned stream encapsulates a {@link DirectoryStream}. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. + * + *

    Operating on a closed stream behaves as if the end of stream * has been reached. Due to read-ahead, one or more elements may be * returned after the stream has been closed. * @@ -3278,7 +3296,7 @@ public final class Files { * * @param dir The path to the directory * - * @return The {@code CloseableStream} describing the content of the + * @return The {@code Stream} describing the content of the * directory * * @throws NotDirectoryException @@ -3294,43 +3312,54 @@ public final class Files { * @see #newDirectoryStream(Path) * @since 1.8 */ - public static CloseableStream list(Path dir) throws IOException { + public static Stream list(Path dir) throws IOException { DirectoryStream ds = Files.newDirectoryStream(dir); - final Iterator delegate = ds.iterator(); + try { + final Iterator delegate = ds.iterator(); - // Re-wrap DirectoryIteratorException to UncheckedIOException - Iterator it = new Iterator() { - public boolean hasNext() { - try { - return delegate.hasNext(); - } catch (DirectoryIteratorException e) { - throw new UncheckedIOException(e.getCause()); + // Re-wrap DirectoryIteratorException to UncheckedIOException + Iterator it = new Iterator() { + @Override + public boolean hasNext() { + try { + return delegate.hasNext(); + } catch (DirectoryIteratorException e) { + throw new UncheckedIOException(e.getCause()); + } } - } - public Path next() { - try { - return delegate.next(); - } catch (DirectoryIteratorException e) { - throw new UncheckedIOException(e.getCause()); + @Override + public Path next() { + try { + return delegate.next(); + } catch (DirectoryIteratorException e) { + throw new UncheckedIOException(e.getCause()); + } } - } - }; + }; - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), - false); - return new DelegatingCloseableStream<>(ds, s); + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(it, Spliterator.DISTINCT), false) + .onClose(asUncheckedRunnable(ds)); + } catch (Error|RuntimeException e) { + try { + ds.close(); + } catch (IOException ex) { + try { + e.addSuppressed(ex); + } catch (Throwable ignore) {} + } + throw e; + } } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by walking the file tree rooted at a given starting file. The * file tree is traversed depth-first, the elements in the stream * are {@link Path} objects that are obtained as if by {@link * Path#resolve(Path) resolving} the relative path against {@code start}. * *

    The {@code stream} walks the file tree as elements are consumed. - * The {@code CloseableStream} returned is guaranteed to have at least one + * The {@code Stream} returned is guaranteed to have at least one * element, the starting file itself. For each file visited, the stream * attempts to read its {@link BasicFileAttributes}. If the file is a * directory and can be opened successfully, entries in the directory, and @@ -3370,10 +3399,11 @@ public final class Files { *

    When a security manager is installed and it denies access to a file * (or directory), then it is ignored and not included in the stream. * - *

    When not using the try-with-resources construct, then the stream's - * {@link CloseableStream#close close} method should be invoked after the - * operation is completed so as to free any resources held for the open - * directory. Operate the stream after it is closed will throw an + *

    The returned stream encapsulates one or more {@link DirectoryStream}s. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. Operating on a closed stream will result in an * {@link java.lang.IllegalStateException}. * *

    If an {@link IOException} is thrown when accessing the directory @@ -3388,7 +3418,7 @@ public final class Files { * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws IllegalArgumentException * if the {@code maxDepth} parameter is negative @@ -3401,21 +3431,22 @@ public final class Files { * if an I/O error is thrown when accessing the starting file. * @since 1.8 */ - public static CloseableStream walk(Path start, int maxDepth, - FileVisitOption... options) - throws IOException - { + public static Stream walk(Path start, int maxDepth, + FileVisitOption... options) + throws IOException { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); - - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), - false). - map(entry -> entry.file()); - return new DelegatingCloseableStream<>(iterator, s); + try { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + .onClose(iterator::close) + .map(entry -> entry.file()); + } catch (Error|RuntimeException e) { + iterator.close(); + throw e; + } } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by walking the file tree rooted at a given starting file. The * file tree is traversed depth-first, the elements in the stream * are {@link Path} objects that are obtained as if by {@link @@ -3428,12 +3459,19 @@ public final class Files { *

    * In other words, it visits all levels of the file tree. * + *

    The returned stream encapsulates one or more {@link DirectoryStream}s. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. Operating on a closed stream will result in an + * {@link java.lang.IllegalStateException}. + * * @param start * the starting file * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws SecurityException * If the security manager denies access to the starting file. @@ -3446,15 +3484,14 @@ public final class Files { * @see #walk(Path, int, FileVisitOption...) * @since 1.8 */ - public static CloseableStream walk(Path start, - FileVisitOption... options) - throws IOException - { + public static Stream walk(Path start, + FileVisitOption... options) + throws IOException { return walk(start, Integer.MAX_VALUE, options); } /** - * Return a {@code CloseableStream} that is lazily populated with {@code + * Return a {@code Stream} that is lazily populated with {@code * Path} by searching for files in a file tree rooted at a given starting * file. * @@ -3463,12 +3500,19 @@ public final class Files { * {@link BiPredicate} is invoked with its {@link Path} and {@link * BasicFileAttributes}. The {@code Path} object is obtained as if by * {@link Path#resolve(Path) resolving} the relative path against {@code - * start} and is only included in the returned {@link CloseableStream} if + * start} and is only included in the returned {@link Stream} if * the {@code BiPredicate} returns true. Compare to calling {@link * java.util.stream.Stream#filter filter} on the {@code Stream} * returned by {@code walk} method, this method may be more efficient by * avoiding redundant retrieval of the {@code BasicFileAttributes}. * + *

    The returned stream encapsulates one or more {@link DirectoryStream}s. + * If timely disposal of file system resources is required, the + * {@code try}-with-resources construct should be used to ensure that the + * stream's {@link Stream#close close} method is invoked after the stream + * operations are completed. Operating on a closed stream will result in an + * {@link java.lang.IllegalStateException}. + * *

    If an {@link IOException} is thrown when accessing the directory * after returned from this method, it is wrapped in an {@link * UncheckedIOException} which will be thrown from the method that caused @@ -3484,7 +3528,7 @@ public final class Files { * @param options * options to configure the traversal * - * @return the {@link CloseableStream} of {@link Path} + * @return the {@link Stream} of {@link Path} * * @throws IllegalArgumentException * if the {@code maxDepth} parameter is negative @@ -3499,24 +3543,25 @@ public final class Files { * @see #walk(Path, int, FileVisitOption...) * @since 1.8 */ - public static CloseableStream find(Path start, - int maxDepth, - BiPredicate matcher, - FileVisitOption... options) - throws IOException - { + public static Stream find(Path start, + int maxDepth, + BiPredicate matcher, + FileVisitOption... options) + throws IOException { FileTreeIterator iterator = new FileTreeIterator(start, maxDepth, options); - - Stream s = StreamSupport.stream( - Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), - false). - filter(entry -> matcher.test(entry.file(), entry.attributes())). - map(entry -> entry.file()); - return new DelegatingCloseableStream<>(iterator, s); + try { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.DISTINCT), false) + .onClose(iterator::close) + .filter(entry -> matcher.test(entry.file(), entry.attributes())) + .map(entry -> entry.file()); + } catch (Error|RuntimeException e) { + iterator.close(); + throw e; + } } /** - * Read all lines from a file as a {@code CloseableStream}. Unlike {@link + * Read all lines from a file as a {@code Stream}. Unlike {@link * #readAllLines(Path, Charset) readAllLines}, this method does not read * all lines into a {@code List}, but instead populates lazily as the stream * is consumed. @@ -3528,22 +3573,24 @@ public final class Files { *

    After this method returns, then any subsequent I/O exception that * occurs while reading from the file or when a malformed or unmappable byte * sequence is read, is wrapped in an {@link UncheckedIOException} that will - * be thrown form the + * be thrown from the * {@link java.util.stream.Stream} method that caused the read to take * place. In case an {@code IOException} is thrown when closing the file, * it is also wrapped as an {@code UncheckedIOException}. * - *

    When not using the try-with-resources construct, then stream's - * {@link CloseableStream#close close} method should be invoked after - * operation is completed so as to free any resources held for the open - * file. + *

    The returned stream encapsulates a {@link Reader}. If timely + * disposal of file system resources is required, the try-with-resources + * construct should be used to ensure that the stream's + * {@link Stream#close close} method is invoked after the stream operations + * are completed. + * * * @param path * the path to the file * @param cs * the charset to use for decoding * - * @return the lines from the file as a {@code CloseableStream} + * @return the lines from the file as a {@code Stream} * * @throws IOException * if an I/O error occurs opening the file @@ -3557,10 +3604,19 @@ public final class Files { * @see java.io.BufferedReader#lines() * @since 1.8 */ - public static CloseableStream lines(Path path, Charset cs) - throws IOException - { + public static Stream lines(Path path, Charset cs) throws IOException { BufferedReader br = Files.newBufferedReader(path, cs); - return new DelegatingCloseableStream<>(br, br.lines()); + try { + return br.lines().onClose(asUncheckedRunnable(br)); + } catch (Error|RuntimeException e) { + try { + br.close(); + } catch (IOException ex) { + try { + e.addSuppressed(ex); + } catch (Throwable ignore) {} + } + throw e; + } } } diff --git a/jdk/src/share/classes/java/rmi/activation/Activatable.java b/jdk/src/share/classes/java/rmi/activation/Activatable.java index 7b43c27bd22..6ab4ba22481 100644 --- a/jdk/src/share/classes/java/rmi/activation/Activatable.java +++ b/jdk/src/share/classes/java/rmi/activation/Activatable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,6 +93,8 @@ public abstract class Activatable extends RemoteServer { * @exception RemoteException if either of the following fails: * a) registering the object with the activation system or b) exporting * the object to the RMI runtime. + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation. * @since 1.2 **/ protected Activatable(String location, @@ -143,6 +145,8 @@ public abstract class Activatable extends RemoteServer { * @exception RemoteException if either of the following fails: * a) registering the object with the activation system or b) exporting * the object to the RMI runtime. + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation. * @since 1.2 **/ protected Activatable(String location, @@ -175,6 +179,8 @@ public abstract class Activatable extends RemoteServer { * @param port the port number on which the object is exported * @exception RemoteException if exporting the object to the RMI * runtime fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ protected Activatable(ActivationID id, int port) @@ -206,6 +212,8 @@ public abstract class Activatable extends RemoteServer { * @param ssf the server-side socket factory for receiving remote calls * @exception RemoteException if exporting the object to the RMI * runtime fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ protected Activatable(ActivationID id, int port, @@ -239,6 +247,8 @@ public abstract class Activatable extends RemoteServer { * is not registered with the activation system * @exception ActivationException if activation system is not running * @exception RemoteException if remote call fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static Remote register(ActivationDesc desc) @@ -273,6 +283,8 @@ public abstract class Activatable extends RemoteServer { * already be inactive) * @exception ActivationException if group is not active * @exception RemoteException if call informing monitor fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static boolean inactive(ActivationID id) @@ -290,6 +302,8 @@ public abstract class Activatable extends RemoteServer { * @exception UnknownObjectException if object (id) is unknown * @exception ActivationException if activation system is not running * @exception RemoteException if remote call to activation system fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static void unregister(ActivationID id) @@ -334,6 +348,8 @@ public abstract class Activatable extends RemoteServer { * the wrong group * @exception ActivationException if activation group is not active * @exception RemoteException if object registration or export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 **/ public static ActivationID exportObject(Remote obj, @@ -407,6 +423,8 @@ public abstract class Activatable extends RemoteServer { * descriptor with the activation system * @exception ActivationException if activation group is not active * @exception RemoteException if object registration or export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 **/ public static ActivationID exportObject(Remote obj, @@ -473,6 +491,8 @@ public abstract class Activatable extends RemoteServer { * @param port the port on which the object is exported (an anonymous * port is used if port=0) * @exception RemoteException if object export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static Remote exportObject(Remote obj, @@ -503,6 +523,8 @@ public abstract class Activatable extends RemoteServer { * remote object * @param ssf the server-side socket factory for receiving remote calls * @exception RemoteException if object export fails + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static Remote exportObject(Remote obj, @@ -531,6 +553,8 @@ public abstract class Activatable extends RemoteServer { * @return true if operation is successful, false otherwise * @exception NoSuchObjectException if the remote object is not * currently exported + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public static boolean unexportObject(Remote obj, boolean force) diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java b/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java index d206337f70f..e9170294d05 100644 --- a/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java +++ b/jdk/src/share/classes/java/rmi/activation/ActivationDesc.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -105,6 +105,8 @@ public final class ActivationDesc implements Serializable { * @param data the object's initialization (activation) data contained * in marshalled form. * @exception ActivationException if the current group is nonexistent + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(String className, @@ -142,6 +144,8 @@ public final class ActivationDesc implements Serializable { * true does not force an initial immediate activation of * a newly registered object; initial activation is lazy. * @exception ActivationException if the current group is nonexistent + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(String className, @@ -176,6 +180,8 @@ public final class ActivationDesc implements Serializable { * @param data the object's initialization (activation) data contained * in marshalled form. * @exception IllegalArgumentException if groupID is null + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(ActivationGroupID groupID, @@ -208,6 +214,8 @@ public final class ActivationDesc implements Serializable { * true does not force an initial immediate activation of * a newly registered object; initial activation is lazy. * @exception IllegalArgumentException if groupID is null + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationDesc(ActivationGroupID groupID, diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java b/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java index 28d41c25b3f..49dffd18e0e 100644 --- a/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java +++ b/jdk/src/share/classes/java/rmi/activation/ActivationGroup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -133,6 +133,8 @@ public abstract class ActivationGroup * * @param groupID the group's identifier * @throws RemoteException if this group could not be exported + * @throws UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ protected ActivationGroup(ActivationGroupID groupID) @@ -267,6 +269,8 @@ public abstract class ActivationGroup * (Note: The default implementation of the security manager * checkSetFactory * method requires the RuntimePermission "setFactory") + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @see SecurityManager#checkSetFactory * @since 1.2 */ @@ -345,6 +349,8 @@ public abstract class ActivationGroup /** * Returns the current activation group's identifier. Returns null * if no group is currently active for this VM. + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @return the activation group's identifier * @since 1.2 */ @@ -394,6 +400,8 @@ public abstract class ActivationGroup * (Note: The default implementation of the security manager * checkSetFactory * method requires the RuntimePermission "setFactory") + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @see #getSystem * @see SecurityManager#checkSetFactory * @since 1.2 @@ -428,6 +436,8 @@ public abstract class ActivationGroup * @exception ActivationException if activation system cannot be * obtained or is not bound * (means that it is not running) + * @exception UnsupportedOperationException if and only if activation is + * not supported by this implementation * @see #setSystem * @since 1.2 */ diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java b/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java index 85c1f0f5906..bbd816fd73e 100644 --- a/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java +++ b/jdk/src/share/classes/java/rmi/activation/ActivationGroupID.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,6 +63,8 @@ public class ActivationGroupID implements java.io.Serializable { * Constructs a unique group id. * * @param system the group's activation system + * @throws UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationGroupID(ActivationSystem system) { diff --git a/jdk/src/share/classes/java/rmi/activation/ActivationID.java b/jdk/src/share/classes/java/rmi/activation/ActivationID.java index 1a5b33ff43c..02511b848b8 100644 --- a/jdk/src/share/classes/java/rmi/activation/ActivationID.java +++ b/jdk/src/share/classes/java/rmi/activation/ActivationID.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,6 +90,8 @@ public class ActivationID implements Serializable { * * @param activator reference to the activator responsible for * activating the object + * @throws UnsupportedOperationException if and only if activation is + * not supported by this implementation * @since 1.2 */ public ActivationID(Activator activator) { diff --git a/jdk/src/share/classes/java/rmi/activation/package.html b/jdk/src/share/classes/java/rmi/activation/package.html index ceb26788d1f..ed4bb79bffe 100644 --- a/jdk/src/share/classes/java/rmi/activation/package.html +++ b/jdk/src/share/classes/java/rmi/activation/package.html @@ -1,5 +1,5 @@ KO!!! "+obj.getClass().getSimpleName()+".hashCode got NPE with a null "+param); + failed++; + } + + try { + obj.toString(); + System.out.println("OK: "+obj.getClass().getSimpleName()+".toString worked with a null "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO!!! "+obj.getClass().getSimpleName()+".toString got NPE."); + failed++; + } + } +} diff --git a/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java b/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java new file mode 100644 index 00000000000..452e940b0fd --- /dev/null +++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoEqualsNPETest.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.OpenMBeanAttributeInfo; +import javax.management.openmbean.OpenMBeanAttributeInfoSupport; +import javax.management.openmbean.OpenMBeanConstructorInfo; +import javax.management.openmbean.OpenMBeanConstructorInfoSupport; +import javax.management.openmbean.OpenMBeanInfo; +import javax.management.openmbean.OpenMBeanInfoSupport; +import javax.management.openmbean.OpenMBeanOperationInfo; +import javax.management.openmbean.OpenMBeanOperationInfoSupport; +import javax.management.openmbean.OpenMBeanParameterInfo; +import javax.management.openmbean.OpenMBeanParameterInfoSupport; +import javax.management.openmbean.SimpleType; + +/* + * @test + * @bug 8023529 + * @summary Test that OpenMBean*Info.equals do not throw NPE + * @author Shanliang JIANG + * @run clean OpenMBeanInfoEqualsNPETest + * @run build OpenMBeanInfoEqualsNPETest + * @run main OpenMBeanInfoEqualsNPETest + */ +public class OpenMBeanInfoEqualsNPETest { + private static int failed = 0; + + public static void main(String[] args) throws Exception { + System.out.println("---OpenMBeanInfoEqualsNPETest-main ..."); + + // ---- + System.out.println("\n---Testing on OpenMBeanAttributeInfoSupport..."); + OpenMBeanAttributeInfo openMBeanAttributeInfo0 = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, 1, new Integer[]{1, 2, 3}); + OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3}); + test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "defaultValue"); + + openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, 1, null); + test(openMBeanAttributeInfo0, openMBeanAttributeInfo, "legalValues"); + + // ---- + System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport..."); + OpenMBeanConstructorInfo openMBeanConstructorInfo0 = new OpenMBeanConstructorInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, new DescriptorSupport()); + OpenMBeanConstructorInfo openMBeanConstructorInfo; + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", null, new DescriptorSupport()); + test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "sigs"); + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, null); + test(openMBeanConstructorInfo0, openMBeanConstructorInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanOperationInfoSupport..."); + OpenMBeanOperationInfo openMBeanOperationInfo0 = new OpenMBeanOperationInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, new DescriptorSupport()); + OpenMBeanOperationInfo openMBeanOperationInfo; + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport()); + test(openMBeanOperationInfo0, openMBeanOperationInfo, "sigs"); + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, MBeanOperationInfo.UNKNOWN, null); + test(openMBeanOperationInfo0, openMBeanOperationInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1..."); + OpenMBeanParameterInfo openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, -1, 1); + OpenMBeanParameterInfo openMBeanParameterInfo; + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, -1, 1); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, null, 1); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "min value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, -1, null); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "max value"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2..."); + openMBeanParameterInfo0 = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2}); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2}); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, null); + test(openMBeanParameterInfo0, openMBeanParameterInfo, "legal values"); + + // ---- + System.out.println("\n---Testing on OpenMBeanInfoSupport..."); + String className = "toto"; + String description = "titi"; + OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{}; + OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{}; + OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{}; + MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{}; + + OpenMBeanInfo ominfo0 = new OpenMBeanInfoSupport("toto", description, attrInfos, constrInfos, operaInfos, notifInfos); + OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo0, ominfo, "class name"); + + ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo0, ominfo, "description"); + + ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos); + test(ominfo0, ominfo, "attrInfos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos); + test(ominfo0, ominfo, "constructor infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos); + test(ominfo0, ominfo, "operation infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null); + test(ominfo0, ominfo, "notif infos"); + + if (failed > 0) { + throw new RuntimeException("Test failed: "+failed); + } else { + System.out.println("---Test: PASSED"); + } + } + + private static void test(Object obj1, Object obj2, String param) { + try { + obj1.equals(obj2); + System.out.println("OK-1: "+obj1.getClass().getSimpleName()+ + ".equals worked with a null field: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj1.getClass().getSimpleName()+ + ".equals got NPE with a null field: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj2.equals(obj1); + System.out.println("OK-2: "+obj2.getClass().getSimpleName()+ + ".equals worked with a null field: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-2!!! "+obj2.getClass().getSimpleName()+ + ".equals got NPE with a null field: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj1.equals(null); + obj2.equals(null); + + System.out.println("OK-3: "+obj1.getClass().getSimpleName()+ + ".equals worked with a null object."); + } catch (NullPointerException npe) { + System.out.println("--->KO-3!!! "+obj1.getClass().getSimpleName()+ + ".equals got NPE with a null object."); + npe.printStackTrace(); + failed++; + } + } +} diff --git a/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java b/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java new file mode 100644 index 00000000000..3c829434193 --- /dev/null +++ b/jdk/test/javax/management/openmbean/OpenMBeanInfoHashCodeNPETest.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.management.MBeanNotificationInfo; +import javax.management.modelmbean.DescriptorSupport; +import javax.management.openmbean.OpenMBeanAttributeInfo; +import javax.management.openmbean.OpenMBeanAttributeInfoSupport; +import javax.management.openmbean.OpenMBeanConstructorInfo; +import javax.management.openmbean.OpenMBeanConstructorInfoSupport; +import javax.management.openmbean.OpenMBeanInfo; +import javax.management.openmbean.OpenMBeanInfoSupport; +import javax.management.openmbean.OpenMBeanOperationInfo; +import javax.management.openmbean.OpenMBeanOperationInfoSupport; +import javax.management.openmbean.OpenMBeanParameterInfo; +import javax.management.openmbean.OpenMBeanParameterInfoSupport; +import javax.management.openmbean.SimpleType; + +/* + * @test + * @bug 8023529 + * @summary Test that OpenMBean*Info.hashCode do not throw NPE + * @author Shanliang JIANG + * @run clean OpenMBeanInfoHashCodeNPETest + * @run build OpenMBeanInfoHashCodeNPETest + * @run main OpenMBeanInfoHashCodeNPETest + */ +public class OpenMBeanInfoHashCodeNPETest { + private static int failed = 0; + + public static void main(String[] args) throws Exception { + System.out.println("---OpenMBeanInfoHashCodeNPETest-main ..."); + + // ---- + System.out.println("\n---Testing on OpenMBeanInfohashCodeTest..."); + OpenMBeanAttributeInfo openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, null, new Integer[]{1, 2, 3}); + test(openMBeanAttributeInfo, "defaultValue"); + + openMBeanAttributeInfo = new OpenMBeanAttributeInfoSupport( + "name", "description", SimpleType.INTEGER, true, true, false, 1, null); + test(openMBeanAttributeInfo, "legalValues"); + + // ---- + System.out.println("\n---Testing on OpenMBeanConstructorInfoSupport..."); + OpenMBeanConstructorInfo openMBeanConstructorInfo; + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", null, new DescriptorSupport()); + test(openMBeanConstructorInfo, "sigs"); + + openMBeanConstructorInfo = new OpenMBeanConstructorInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, null); + test(openMBeanConstructorInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanOperationInfoSupport..."); + OpenMBeanOperationInfo openMBeanOperationInfo; + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", null, SimpleType.INTEGER, 1, new DescriptorSupport()); + test(openMBeanOperationInfo, "sigs"); + + openMBeanOperationInfo = new OpenMBeanOperationInfoSupport( + "name", "description", new OpenMBeanParameterInfo[]{}, SimpleType.INTEGER, 1, null); + test(openMBeanOperationInfo, "Descriptor"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 1..."); + OpenMBeanParameterInfo openMBeanParameterInfo; + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, -1, 1); + test(openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, null, 1); + test(openMBeanParameterInfo, "min value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 0, -1, null); + test(openMBeanParameterInfo, "max value"); + + // ---- + System.out.println("\n---Testing on OpenMBeanParameterInfoSupport 2..."); + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, new Integer[]{-1, 1, 2}); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, null, new Integer[]{-1, 1, 2}); + test(openMBeanParameterInfo, "default value"); + + openMBeanParameterInfo = new OpenMBeanParameterInfoSupport( + "name", "description", SimpleType.INTEGER, 1, null); + test(openMBeanParameterInfo, "legal values"); + + // ---- + System.out.println("\n---Testing on OpenMBeanInfoSupport..."); + String className = "toto"; + String description = "titi"; + OpenMBeanAttributeInfo[] attrInfos = new OpenMBeanAttributeInfo[]{}; + OpenMBeanConstructorInfo[] constrInfos = new OpenMBeanConstructorInfo[]{}; + OpenMBeanOperationInfo[] operaInfos = new OpenMBeanOperationInfo[]{}; + MBeanNotificationInfo[] notifInfos = new MBeanNotificationInfo[]{}; + + OpenMBeanInfo ominfo = new OpenMBeanInfoSupport(null, description, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo, "class name"); + + ominfo = new OpenMBeanInfoSupport(className, null, attrInfos, constrInfos, operaInfos, notifInfos); + test(ominfo, "description"); + + ominfo = new OpenMBeanInfoSupport(className, description, null, constrInfos, operaInfos, notifInfos); + test(ominfo, "attrInfos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, null, operaInfos, notifInfos); + test(ominfo, "constructor infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, null, notifInfos); + test(ominfo, "operation infos"); + + ominfo = new OpenMBeanInfoSupport(className, description, attrInfos, constrInfos, operaInfos, null); + test(ominfo, "notif infos"); + + if (failed > 0) { + throw new RuntimeException("Test failed: "+failed); + } else { + System.out.println("---Test: PASSED"); + } + } + + private static void test(Object obj, String param) { + try { + obj.hashCode(); + System.out.println("OK-1: "+obj.getClass().getSimpleName()+ + ".hashCode worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+ + ".hashCode got NPE with null paramer: "+param); + npe.printStackTrace(); + failed++; + } + + try { + obj.toString(); + System.out.println("OK-1: "+obj.getClass().getSimpleName()+ + ".toString worked with a null paramer: "+param); + } catch (NullPointerException npe) { + System.out.println("--->KO-1!!! "+obj.getClass().getSimpleName()+ + ".toString got NPE with null paramer: "+param); + npe.printStackTrace(); + failed++; + } + } +} diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java new file mode 100644 index 00000000000..86efed134f3 --- /dev/null +++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.management.ManagementFactory; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXPrincipal; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnector; +import javax.security.auth.Subject; + +/* + * @test + * @bug 6566891 + * @summary Check no memory leak on RMIConnector's rmbscMap + * @author Shanliang JIANG + * @run clean RMIConnectorInternalMapTest + * @run build RMIConnectorInternalMapTest + * @run main RMIConnectorInternalMapTest + */ + +public class RMIConnectorInternalMapTest { + public static void main(String[] args) throws Exception { + System.out.println("---RMIConnectorInternalMapTest starting..."); + + JMXConnectorServer connectorServer = null; + JMXConnector connectorClient = null; + + try { + MBeanServer mserver = ManagementFactory.getPlatformMBeanServer(); + JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0); + connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver); + connectorServer.start(); + + JMXServiceURL serverAddr = connectorServer.getAddress(); + connectorClient = JMXConnectorFactory.connect(serverAddr, null); + connectorClient.connect(); + + Field rmbscMapField = RMIConnector.class.getDeclaredField("rmbscMap"); + rmbscMapField.setAccessible(true); + Map> map = + (Map>) rmbscMapField.get(connectorClient); + if (map != null && !map.isEmpty()) { // failed + throw new RuntimeException("RMIConnector's rmbscMap must be empty at the initial time."); + } + + Subject delegationSubject = + new Subject(true, + Collections.singleton(new JMXPrincipal("delegate")), + Collections.EMPTY_SET, + Collections.EMPTY_SET); + MBeanServerConnection mbsc1 = + connectorClient.getMBeanServerConnection(delegationSubject); + MBeanServerConnection mbsc2 = + connectorClient.getMBeanServerConnection(delegationSubject); + + if (mbsc1 == null) { + throw new RuntimeException("Got null connection."); + } + if (mbsc1 != mbsc2) { + throw new RuntimeException("Not got same connection with a same subject."); + } + + map = (Map>) rmbscMapField.get(connectorClient); + if (map == null || map.isEmpty()) { // failed + throw new RuntimeException("RMIConnector's rmbscMap has wrong size " + + "after creating a delegated connection."); + } + + delegationSubject = null; + mbsc1 = null; + mbsc2 = null; + + int i = 0; + while (!map.isEmpty() && i++ < 60) { + System.gc(); + Thread.sleep(100); + } + System.out.println("---GC times: " + i); + + if (!map.isEmpty()) { + throw new RuntimeException("Failed to clean RMIConnector's rmbscMap"); + } else { + System.out.println("---RMIConnectorInternalMapTest: PASSED!"); + } + } finally { + try { + connectorClient.close(); + connectorServer.stop(); + } catch (Exception e) { + } + } + } +} diff --git a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java new file mode 100644 index 00000000000..7b5224e9b92 --- /dev/null +++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.management.ManagementFactory; +import java.lang.ref.WeakReference; +import java.lang.reflect.Field; +import javax.management.MBeanServer; +import javax.management.MBeanServerConnection; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.rmi.RMIConnector; + +/* + * @test + * @bug 6566891 + * @summary Check no memory leak on RMIConnector's nullSubjectConn + * @author Shanliang JIANG + * @run clean RMIConnectorNullSubjectConnTest + * @run build RMIConnectorNullSubjectConnTest + * @run main RMIConnectorNullSubjectConnTest + */ + +public class RMIConnectorNullSubjectConnTest { + public static void main(String[] args) throws Exception { + System.out.println("---RMIConnectorNullSubjectConnTest starting..."); + + JMXConnectorServer connectorServer = null; + JMXConnector connectorClient = null; + + try { + MBeanServer mserver = ManagementFactory.getPlatformMBeanServer(); + JMXServiceURL serverURL = new JMXServiceURL("rmi", "localhost", 0); + connectorServer = JMXConnectorServerFactory.newJMXConnectorServer(serverURL, null, mserver); + connectorServer.start(); + + JMXServiceURL serverAddr = connectorServer.getAddress(); + connectorClient = JMXConnectorFactory.connect(serverAddr, null); + connectorClient.connect(); + + Field nullSubjectConnField = RMIConnector.class.getDeclaredField("nullSubjectConnRef"); + nullSubjectConnField.setAccessible(true); + + WeakReference weak = + (WeakReference)nullSubjectConnField.get(connectorClient); + + if (weak != null && weak.get() != null) { + throw new RuntimeException("nullSubjectConnRef must be null at initial time."); + } + + MBeanServerConnection conn1 = connectorClient.getMBeanServerConnection(null); + MBeanServerConnection conn2 = connectorClient.getMBeanServerConnection(null); + if (conn1 == null) { + throw new RuntimeException("A connection with null subject should not be null."); + } else if (conn1 != conn2) { + throw new RuntimeException("The 2 connections with null subject are not equal."); + } + + conn1 = null; + conn2 = null; + int i = 1; + do { + System.gc(); + Thread.sleep(100); + weak = (WeakReference)nullSubjectConnField.get(connectorClient); + } while ((weak != null && weak.get() != null) && i++ < 60); + + System.out.println("---GC times: " + i); + + if (weak != null && weak.get() != null) { + throw new RuntimeException("Failed to clean RMIConnector's nullSubjectConn"); + } else { + System.out.println("---RMIConnectorNullSubjectConnTest: PASSED!"); + } + } finally { + try { + connectorClient.close(); + connectorServer.stop(); + } catch (Exception e) { + } + } + } +} diff --git a/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java new file mode 100644 index 00000000000..805a6a203cb --- /dev/null +++ b/jdk/test/jdk/lambda/MethodReferenceTestCallerSensitive.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import org.testng.annotations.Test; + +import java.lang.reflect.Field; +import java.util.function.Function; + + +/** + * @author Robert Field + */ + +@Test +public class MethodReferenceTestCallerSensitive { + + private static void getF(T arg) { + Function,Field[]> firstFunction = Class::getFields; + } + + public void testConstructorReferenceVarArgs() { + getF("Hello World"); + } + +} diff --git a/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java b/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java new file mode 100644 index 00000000000..ab8527d76da --- /dev/null +++ b/jdk/test/sun/java2d/cmm/ProfileOp/DisposalCrashTest.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8024511 + * @summary Verifies that instances of color profiles are destroyed correctly. + * A crash during profile destruction indicates failure. + * + * @run main DisposalCrashTest + */ + +import static java.awt.color.ColorSpace.*; +import java.awt.color.ICC_Profile; +import java.lang.ref.Reference; +import java.lang.ref.ReferenceQueue; +import java.lang.ref.WeakReference; +import java.util.Vector; + +public class DisposalCrashTest { + + static final ReferenceQueue queue = new ReferenceQueue<>(); + static final Vector> v = new Vector<>(); + + public static void main(String[] args) { + int[] ids = new int[]{ + CS_sRGB, CS_CIEXYZ, CS_GRAY, CS_LINEAR_RGB, CS_PYCC + }; + + for (int id : ids) { + ICC_Profile p = getCopyOf(id); + } + + while (!v.isEmpty()) { + System.gc(); + System.out.println("."); + try { + Thread.sleep(500); + } catch (InterruptedException e) {}; + + final Reference ref = queue.poll(); + System.out.println("Got reference: " + ref); + + v.remove(ref); + } + + System.out.println("Test PASSED."); + } + + private static ICC_Profile getCopyOf(int id) { + ICC_Profile std = ICC_Profile.getInstance(id); + + byte[] data = std.getData(); + + ICC_Profile p = ICC_Profile.getInstance(data); + + WeakReference ref = new WeakReference<>(p, queue); + + v.add(ref); + + return p; + } +} diff --git a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java index bc14128fcee..f3fa0791d46 100644 --- a/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java +++ b/jdk/test/sun/java2d/cmm/ProfileOp/ReadWriteProfileTest.java @@ -23,7 +23,7 @@ /** * @test - * @bug 6476665 6523403 6733501 7042594 + * @bug 6476665 6523403 6733501 7042594 7043064 * @summary Verifies reading and writing profiles and tags of the standard color * spaces * @run main ReadWriteProfileTest @@ -82,6 +82,7 @@ public class ReadWriteProfileTest implements Runnable { public void run() { for (int i = 0; i < cspaces.length; i++) { + System.out.println("Profile: " + csNames[i]); ICC_Profile pf = ICC_Profile.getInstance(cspaces[i]); byte [] data = pf.getData(); pf = ICC_Profile.getInstance(data); @@ -92,6 +93,10 @@ public class ReadWriteProfileTest implements Runnable { } for (int tagSig : tags[i].keySet()) { + String signature = SigToString(tagSig); + System.out.printf("Tag: %s\n", signature); + System.out.flush(); + byte [] tagData = pf.getData(tagSig); byte [] empty = new byte[tagData.length]; boolean emptyDataRejected = false; @@ -104,15 +109,23 @@ public class ReadWriteProfileTest implements Runnable { throw new RuntimeException("Test failed: empty tag data was not rejected."); } - pf.setData(tagSig, tagData); - + try { + pf.setData(tagSig, tagData); + } catch (IllegalArgumentException e) { + // let's ignore this exception for Kodak proprietary tags + if (isKodakExtention(signature)) { + System.out.println("Ignore Kodak tag: " + signature); + } else { + throw new RuntimeException("Test failed!", e); + } + } byte [] tagData1 = pf.getData(tagSig); if (!Arrays.equals(tagData1, tags[i].get(tagSig))) { System.err.println("Incorrect result of getData(int) with" + " tag " + - Integer.toHexString(tagSig) + + SigToString(tagSig) + " of " + csNames[i] + " profile"); throw new RuntimeException("Incorrect result of " + @@ -122,6 +135,19 @@ public class ReadWriteProfileTest implements Runnable { } } + private static boolean isKodakExtention(String signature) { + return signature.matches("K\\d\\d\\d"); + } + + private static String SigToString(int tagSig ) { + return String.format("%c%c%c%c", + (char)(0xff & (tagSig >> 24)), + (char)(0xff & (tagSig >> 16)), + (char)(0xff & (tagSig >> 8)), + (char)(0xff & (tagSig))); + + } + public static void main(String [] args) { ReadWriteProfileTest test = new ReadWriteProfileTest(); test.run(); diff --git a/jdk/test/sun/security/krb5/runNameEquals.sh b/jdk/test/sun/security/krb5/runNameEquals.sh index 6db90c35315..b9cfb08d8b5 100644 --- a/jdk/test/sun/security/krb5/runNameEquals.sh +++ b/jdk/test/sun/security/krb5/runNameEquals.sh @@ -22,7 +22,7 @@ # # @test -# @bug 6317711 6944847 +# @bug 6317711 6944847 8024046 # @summary Ensure the GSSName has the correct impl which respects # the contract for equals and hashCode across different configurations. @@ -56,6 +56,15 @@ case "$OS" in PATHSEP=":" FILESEP="/" NATIVE=true + # Not all *nix has native GSS libs installed + krb5-config --libs gssapi 2> /dev/null + if [ $? != 0 ]; then + # Fedora has a different path + /usr/kerberos/bin/krb5-config --libs gssapi 2> /dev/null + if [ $? != 0 ]; then + NATIVE=false + fi + fi ;; CYGWIN* ) PATHSEP=";" diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java index c6dd8ce9720..b64d424fe88 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseEngineException.java @@ -21,17 +21,24 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4969799 * @summary javax.net.ssl.SSLSocket.SSLSocket(InetAddress,int) shouldn't * throw exception - * - * This is making sure that starting a new handshake throws the right - * exception. There is a similar test for SSLSocket. - * + * @run main/othervm CloseEngineException */ +// +// This is making sure that starting a new handshake throws the right +// exception. There is a similar test for SSLSocket. +// + import javax.net.ssl.*; import javax.net.ssl.SSLEngineResult.*; import java.io.*; diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java index 7d9274af36e..1c6103bb353 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseInboundException.java @@ -21,11 +21,17 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4931274 * @summary closeInbound does not signal when a close_notify has not * been received. + * @run main/othervm CloseInboundException * @author Brad Wetmore */ diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java index 57224816b71..3c3e2e22b3d 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/CloseStart.java @@ -21,15 +21,22 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 5019096 * @summary Add scatter/gather APIs for SSLEngine - * - * Check to see if the args are being parsed properly. - * + * @run main/othervm CloseStart */ +// +// Check to see if the args are being parsed properly. +// + import javax.net.ssl.*; import javax.net.ssl.SSLEngineResult.*; import java.io.*; diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java index f9548d60be5..e912ff69b95 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/DelegatedTaskWrongException.java @@ -21,11 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4969459 * @summary Delegated tasks are not reflecting the subclasses of SSLException - * + * @run main/othervm DelegatedTaskWrongException */ import javax.net.ssl.*; diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java index f77938869f3..49387e3589b 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EmptyExtensionData.java @@ -21,10 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 6728126 * @summary Parsing Extensions in Client Hello message is done in a wrong way + * @run main/othervm EmptyExtensionData */ import javax.net.ssl.*; diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java index ed1f84caeef..b7a1a9c509a 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/EngineEnforceUseClientMode.java @@ -21,11 +21,16 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 4980882 * @summary SSLEngine should enforce setUseClientMode - * + * @run main/othervm EngineEnforceUseClientMode * @author Brad R. Wetmore */ diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java index da8e591d922..fbe2f2e7854 100644 --- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java +++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java @@ -21,16 +21,21 @@ * questions. */ +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + /* * @test * @bug 6207322 * @summary SSLEngine is returning a premature FINISHED message when doing - * an abbreviated handshake. + * an abbreviated handshake. * @run main/othervm RehandshakeFinished - * - * SunJSSE does not support dynamic system properties, no way to re-use - * system properties in samevm/agentvm mode. - * + * @author Brad Wetmore + */ + +/* * This test may need some updating if the messages change order. * Currently I'm expecting that there is a simple renegotiation, with * each message being contained in a single SSL packet. @@ -41,8 +46,6 @@ * FINISHED * CCS * FINISHED - * - * @author Brad Wetmore */ /** diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java new file mode 100644 index 00000000000..c25d74c7d2c --- /dev/null +++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLParameters/UseCipherSuitesOrder.java @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// +// SunJSSE does not support dynamic system properties, no way to re-use +// system properties in samevm/agentvm mode. +// + +/* + * @test + * @bug 7188657 + * @summary There should be a way to reorder the JSSE ciphers + * @run main/othervm UseCipherSuitesOrder + * TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA + */ + +import java.io.*; +import java.net.*; +import javax.net.ssl.*; +import java.util.Arrays; + +public class UseCipherSuitesOrder { + + /* + * ============================================================= + * Set the various variables needed for the tests, then + * specify what tests to run on each side. + */ + + /* + * Should we run the client or server in a separate thread? + * Both sides can throw exceptions, but do you have a preference + * as to which side should be the main thread. + */ + static boolean separateServerThread = false; + + /* + * Where do we find the keystores? + */ + static String pathToStores = "../../../../etc"; + static String keyStoreFile = "keystore"; + static String trustStoreFile = "truststore"; + static String passwd = "passphrase"; + + /* + * Is the server ready to serve? + */ + volatile static boolean serverReady = false; + + /* + * Turn on SSL debugging? + */ + static boolean debug = false; + + /* + * If the client or server is doing some kind of object creation + * that the other side depends on, and that thread prematurely + * exits, you may experience a hang. The test harness will + * terminate all hung threads after its timeout has expired, + * currently 3 minutes by default, but you might try to be + * smart about it.... + */ + + /* + * Define the server side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doServerSide() throws Exception { + SSLServerSocketFactory sslssf = + (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); + SSLServerSocket sslServerSocket = + (SSLServerSocket) sslssf.createServerSocket(serverPort); + serverPort = sslServerSocket.getLocalPort(); + + // use local cipher suites preference + SSLParameters params = sslServerSocket.getSSLParameters(); + params.setUseCipherSuitesOrder(true); + params.setCipherSuites(srvEnabledCipherSuites); + sslServerSocket.setSSLParameters(params); + + /* + * Signal Client, we're ready for his connect. + */ + serverReady = true; + + SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslIS.read(); + sslOS.write(85); + sslOS.flush(); + + SSLSession session = sslSocket.getSession(); + if (!srvEnabledCipherSuites[0].equals(session.getCipherSuite())) { + throw new Exception( + "Expected to negotiate " + srvEnabledCipherSuites[0] + + " , but not " + session.getCipherSuite()); + } + + sslSocket.close(); + } + + /* + * Define the client side of the test. + * + * If the server prematurely exits, serverReady will be set to true + * to avoid infinite hangs. + */ + void doClientSide() throws Exception { + + /* + * Wait for server to get started. + */ + while (!serverReady) { + Thread.sleep(50); + } + + SSLSocketFactory sslsf = + (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocket sslSocket = (SSLSocket) + sslsf.createSocket("localhost", serverPort); + sslSocket.setEnabledCipherSuites(cliEnabledCipherSuites); + + InputStream sslIS = sslSocket.getInputStream(); + OutputStream sslOS = sslSocket.getOutputStream(); + + sslOS.write(280); + sslOS.flush(); + sslIS.read(); + + sslSocket.close(); + } + + // client enabled cipher suites + private static String[] cliEnabledCipherSuites; + + // server enabled cipher suites + private static String[] srvEnabledCipherSuites; + + private static void parseArguments(String[] args) throws Exception { + if (args.length != 1) { + System.out.println("Usage: java UseCipherSuitesOrder ciphersuites"); + System.out.println("\tciphersuites: " + + "a list of enabled cipher suites, separated with comma"); + throw new Exception("Incorrect usage"); + } + + cliEnabledCipherSuites = args[0].split(","); + + if (cliEnabledCipherSuites.length < 2) { + throw new Exception("Need to enable at least two cipher suites"); + } + + // Only need to use 2 cipher suites in server side. + srvEnabledCipherSuites = Arrays.copyOf( + cliEnabledCipherSuites, 2); + + // Reverse the cipher suite preference in server side. + srvEnabledCipherSuites[0] = cliEnabledCipherSuites[1]; + srvEnabledCipherSuites[1] = cliEnabledCipherSuites[0]; + } + + /* + * ============================================================= + * The remainder is just support stuff + */ + + // use any free port by default + volatile int serverPort = 0; + + volatile Exception serverException = null; + volatile Exception clientException = null; + + public static void main(String[] args) throws Exception { + // parse the arguments + parseArguments(args); + + String keyFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + keyStoreFile; + String trustFilename = + System.getProperty("test.src", ".") + "/" + pathToStores + + "/" + trustStoreFile; + + System.setProperty("javax.net.ssl.keyStore", keyFilename); + System.setProperty("javax.net.ssl.keyStorePassword", passwd); + System.setProperty("javax.net.ssl.trustStore", trustFilename); + System.setProperty("javax.net.ssl.trustStorePassword", passwd); + + if (debug) + System.setProperty("javax.net.debug", "all"); + + /* + * Start the tests. + */ + new UseCipherSuitesOrder(); + } + + Thread clientThread = null; + Thread serverThread = null; + + /* + * Primary constructor, used to drive remainder of the test. + * + * Fork off the other side, then do your work. + */ + UseCipherSuitesOrder() throws Exception { + Exception startException = null; + try { + if (separateServerThread) { + startServer(true); + startClient(false); + } else { + startClient(true); + startServer(false); + } + } catch (Exception e) { + startException = e; + } + + /* + * Wait for other side to close down. + */ + if (separateServerThread) { + if (serverThread != null) { + serverThread.join(); + } + } else { + if (clientThread != null) { + clientThread.join(); + } + } + + /* + * When we get here, the test is pretty much over. + * Which side threw the error? + */ + Exception local; + Exception remote; + + if (separateServerThread) { + remote = serverException; + local = clientException; + } else { + remote = clientException; + local = serverException; + } + + Exception exception = null; + + /* + * Check various exception conditions. + */ + if ((local != null) && (remote != null)) { + // If both failed, return the curthread's exception. + local.initCause(remote); + exception = local; + } else if (local != null) { + exception = local; + } else if (remote != null) { + exception = remote; + } else if (startException != null) { + exception = startException; + } + + /* + * If there was an exception *AND* a startException, + * output it. + */ + if (exception != null) { + if (exception != startException && startException != null) { + exception.addSuppressed(startException); + } + throw exception; + } + + // Fall-through: no exception to throw! + } + + void startServer(boolean newThread) throws Exception { + if (newThread) { + serverThread = new Thread() { + public void run() { + try { + doServerSide(); + } catch (Exception e) { + /* + * Our server thread just died. + * + * Release the client, if not active already... + */ + System.err.println("Server died..."); + serverReady = true; + serverException = e; + } + } + }; + serverThread.start(); + } else { + try { + doServerSide(); + } catch (Exception e) { + serverException = e; + } finally { + serverReady = true; + } + } + } + + void startClient(boolean newThread) throws Exception { + if (newThread) { + clientThread = new Thread() { + public void run() { + try { + doClientSide(); + } catch (Exception e) { + /* + * Our client thread just died. + */ + System.err.println("Client died..."); + clientException = e; + } + } + }; + clientThread.start(); + } else { + try { + doClientSide(); + } catch (Exception e) { + clientException = e; + } + } + } +} diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java index 4d5460739cd..a6a6912c0aa 100644 --- a/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java +++ b/jdk/test/sun/security/ssl/javax/net/ssl/ServerName/IllegalSNIName.java @@ -34,7 +34,7 @@ public class IllegalSNIName { public static void main(String[] args) throws Exception { String[] illegalNames = { - "example\u3003\u3002com", + "example\u3002\u3002com", "example..com", "com\u3002", "com.", diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java deleted file mode 100644 index 082776667a4..00000000000 --- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * - * - * This isn't the test case: ImmutableResourceTest.sh is. - * Refer to ImmutableResourceTest.sh when running this test. - * - * @bug 6287579 - * @summary SubClasses of ListResourceBundle should fix getContents() - */ -import java.util.ResourceBundle; - -public class ImmutableResourceTest { - - public static void main(String[] args) throws Exception { - - /* Reach under the covers and get the message strings */ - sun.tools.jconsole.resources.JConsoleResources jcr = - new sun.tools.jconsole.resources.JConsoleResources (); - Object [][] testData = jcr.getContents(); - - /* Shred our copy of the message strings */ - for (int ii = 0; ii < testData.length; ii++) { - testData[ii][0] = "xxx"; - testData[ii][1] = "yyy"; - } - - /* - * Try a lookup for the shredded key. - * If this is successful we have a problem. - */ - String ss = sun.tools.jconsole.Resources.getText("xxx"); - if ("yyy".equals(ss)) { - throw new Exception ("SubClasses of ListResourceBundle should fix getContents()"); - } - System.out.println("...Finished."); - } -} diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh deleted file mode 100644 index dedf21271b0..00000000000 --- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh +++ /dev/null @@ -1,111 +0,0 @@ -# -# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. -# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# -# This code is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License version 2 only, as -# published by the Free Software Foundation. -# -# This code is distributed in the hope that it will be useful, but WITHOUT -# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -# version 2 for more details (a copy is included in the LICENSE file that -# accompanied this code). -# -# You should have received a copy of the GNU General Public License version -# 2 along with this work; if not, write to the Free Software Foundation, -# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# -# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -# or visit www.oracle.com if you need additional information or have any -# questions. -# - -# @test -# @bug 6287579 -# @summary SubClasses of ListResourceBundle should fix getContents() -# -# @run shell ImmutableResourceTest.sh - -# Beginning of subroutines: -status=1 - -#Call this from anywhere to fail the test with an error message -# usage: fail "reason why the test failed" -fail() - { echo "The test failed :-(" - echo "$*" 1>&2 - echo "exit status was $status" - exit $status - } #end of fail() - -#Call this from anywhere to pass the test with a message -# usage: pass "reason why the test passed if applicable" -pass() - { echo "The test passed!!!" - echo "$*" 1>&2 - exit 0 - } #end of pass() - -# end of subroutines - -# The beginning of the script proper - -OS=`uname -s` -case "$OS" in - SunOS | Linux | Darwin ) - PATHSEP=":" - ;; - - Windows* | CYGWIN*) - PATHSEP=";" - ;; - - # catch all other OSs - * ) - echo "Unrecognized system! $OS" - fail "Unrecognized system! $OS" - ;; -esac - -TARGETCLASS="ImmutableResourceTest" -if [ -z "${TESTJAVA}" ] ; then - # TESTJAVA is not set, so the test is running stand-alone. - # TESTJAVA holds the path to the root directory of the build of the JDK - # to be tested. That is, any java files run explicitly in this shell - # should use TESTJAVA in the path to the java interpreter. - # So, we'll set this to the JDK spec'd on the command line. If none - # is given on the command line, tell the user that and use a default. - # THIS IS THE JDK BEING TESTED. - if [ -n "$1" ] ; then - TESTJAVA=$1 - else - TESTJAVA=$JAVA_HOME - fi - TESTSRC=. - TESTCLASSES=. - #Deal with .class files: -fi -# -echo "JDK under test is: $TESTJAVA" -# -CP="-classpath ${TESTCLASSES}${PATHSEP}${TESTJAVA}/lib/jconsole.jar" -# Compile the test class using the classpath we need: -# -env -# -set -vx -# -#Compile. jconsole.jar is required on the classpath. -${TESTJAVA}/bin/javac -d "${TESTCLASSES}" ${CP} -g \ - "${TESTSRC}"/"${TARGETCLASS}".java -# -#Run the test class, again with the classpath we need: -${TESTJAVA}/bin/java ${CP} ${TARGETCLASS} -status=$? -echo "test status was: $status" -if [ $status -eq "0" ]; - then pass "" - - else fail "unspecified test failure" -fi diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java index 6d4e27be860..1ed5bb642c7 100644 --- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.java +++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,377 +27,134 @@ * This isn't the test case: ResourceCheckTest.sh is. * Refer to ResourceCheckTest.sh when running this test. * - * @bug 5008856 5023573 5024917 5062569 + * @bug 5008856 5023573 5024917 5062569 7172176 * @summary 'missing resource key' error for key = "Operating system" */ -import java.awt.event.KeyEvent; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.ResourceBundle; +import sun.tools.jconsole.Messages; import sun.tools.jconsole.Resources; +/* + * Ensures that there is a one-to-one mapping between constants in the + * Message class and the keys in the sun.tools.jconsole.resources.messages + * bundle. + * + * An error will be thrown if there is a: + * + * - key in the resource bundle that doesn't have a public static field with + * the same name in the Message class. + * + * - public static field in the Message class that doesn't have a key with + * the same name in the resource bundle. + * + * - message with a mnemonic identifier(&) for which a mnemonic can't + * be looked up using Resources#getMnemonicInt(). + * + */ public class ResourceCheckTest { + private static final String MISSING_RESOURCE_KEY_PREFIX = "missing message for"; + private static final String RESOURCE_BUNDLE = "sun.tools.jconsole.resources.messages"; + private static final String NEW_LINE = String.format("%n"); - public static void main(String[] args){ - Object [][] testData = { - {"<", "", "", "", ""}, - {"<<", "", "", "", ""}, - {">", "", "", "", ""}, - {" 1 day", "", "", "", ""}, - {" 1 hour", "", "", "", ""}, - {" 1 min", "", "", "", ""}, - {" 1 month", "", "", "", ""}, - {" 1 year", "", "", "", ""}, - {" 2 hours", "", "", "", ""}, - {" 3 hours", "", "", "", ""}, - {" 3 months", "", "", "", ""}, - {" 5 min", "", "", "", ""}, - {" 6 hours", "", "", "", ""}, - {" 6 months", "", "", "", ""}, - {" 7 days", "", "", "", ""}, - {"10 min", "", "", "", ""}, - {"12 hours", "", "", "", ""}, - {"30 min", "", "", "", ""}, - {"ACTION", "", "", "", ""}, - {"ACTION_INFO", "", "", "", ""}, - {"All", "", "", "", ""}, - {"Architecture", "", "", "", ""}, - {"Attribute", "", "", "", ""}, - {"Attribute value", "", "", "", ""}, - {"Attribute values", "", "", "", ""}, - {"Attributes", "", "", "", ""}, - {"Blank", "", "", "", ""}, - {"BlockedCount WaitedCount", "BlockedCount", "WaitedCount", "", ""}, - {"Boot class path", "", "", "", ""}, - {"BorderedComponent.moreOrLessButton.toolTip", "", "", "", ""}, - {"Close", "", "", "", ""}, - {"CPU Usage", "", "", "", ""}, - {"CPUUsageFormat","PhonyPercentage", "", "", ""}, - {"Cancel", "", "", "", ""}, - {"Cascade", "", "", "", ""}, - {"Cascade.mnemonic", "", "", "", ""}, - {"Chart:", "", "", "", ""}, - {"Chart:.mnemonic", "", "", "", ""}, - {"ClassTab.infoLabelFormat", "LoadedCount", "UnloadedCount", "TotalCount", ""}, - {"ClassTab.loadedClassesPlotter.accessibleName", "", "", "", ""}, - {"Class path", "", "", "", ""}, - {"Classes", "", "", "", ""}, - {"ClassName", "", "", "", ""}, - {"Column.Name", "", "", "", ""}, - {"Column.PID", "", "", "", ""}, - {"Committed", "", "", "", ""}, - {"Committed memory", "", "", "", ""}, - {"Committed virtual memory", "", "", "", ""}, - {"Compiler", "", "", "", ""}, - {"Connect...", "", "", "", ""}, - {"Connect", "", "", "", ""}, - {"Connect.mnemonic", "", "", "", ""}, - {"ConnectDialog.connectButton.toolTip", "", "", "", ""}, - {"ConnectDialog.accessibleDescription", "", "", "", ""}, - {"ConnectDialog.masthead.accessibleName", "", "", "", ""}, - {"ConnectDialog.masthead.title", "", "", "", ""}, - {"ConnectDialog.statusBar.accessibleName", "", "", "", ""}, - {"ConnectDialog.title", "", "", "", ""}, - {"Connected. Click to disconnect.", "", "", "", ""}, - {"connectingTo1", "PhonyConnectionName", "", "", ""}, - {"connectingTo2", "PhonyConnectionName", "", "", ""}, - {"connectionFailed1", "", "", "", ""}, - {"connectionFailed2", "PhonyConnectionName", "", "", ""}, - {"connectionLost1", "", "", "", ""}, - {"connectionLost2", "PhonyConnectionName", "", "", ""}, - {"Connection failed", "", "", "", ""}, - {"Connection", "", "", "", ""}, - {"Connection.mnemonic", "", "", "", ""}, - {"Connection name", "", "", "", ""}, - {"ConnectionName (disconnected)", "Phony", "Phony", "", ""}, - {"Constructor", "", "", "", ""}, - {"Create", "Phony", "Phony", "", ""}, - {"Current classes loaded", "", "", "", ""}, - {"Current heap size", "", "", "", ""}, - {"Current value", "PhonyValue", "", "", ""}, - {"Daemon threads", "", "", "", ""}, - {"deadlockAllTab", "", "", "", ""}, - {"deadlockTab", "", "", "", ""}, - {"deadlockTabN", "PhonyInt", "", "", ""}, - {"Description", "", "", "", ""}, - {"Descriptor", "", "", "", ""}, - {"Details", "", "", "", ""}, - {"Detect Deadlock", "", "", "", ""}, - {"Detect Deadlock.mnemonic", "", "", "", ""}, - {"Detect Deadlock.toolTip", "", "", "", ""}, - {"Dimension is not supported:", "", "", "", ""}, - {"Discard chart", "", "", "", ""}, - {"Disconnected. Click to connect.", "", "", "", ""}, - {"Double click to expand/collapse", "", "", "", ""}, - {"Double click to visualize", "", "", "", ""}, - {"DurationDaysHoursMinutes", 0, 13, 54, ""}, - {"DurationDaysHoursMinutes", 1, 13, 54, ""}, - {"DurationDaysHoursMinutes", 2, 13, 54, ""}, - {"DurationDaysHoursMinutes", 1024, 13, 45, ""}, - {"DurationHoursMinutes", 0, 13, "", ""}, - {"DurationHoursMinutes", 1, 0, "", ""}, - {"DurationHoursMinutes", 1, 1, "", ""}, - {"DurationHoursMinutes", 2, 42, "", ""}, - {"DurationMinutes", 0, "", "", ""}, - {"DurationMinutes", 1, "", "", ""}, - {"DurationMinutes", 2, "", "", ""}, - {"DurationSeconds", 0, "", "", ""}, - {"DurationSeconds", 1, "", "", ""}, - {"DurationSeconds", 2, "", "", ""}, - {"Empty array", "", "", "", ""}, - {"Error", "", "", "", ""}, - {"Error: MBeans already exist", "", "", "", ""}, - {"Error: MBeans do not exist", "", "", "", ""}, - {"Event", "", "", "", ""}, - {"Exit", "", "", "", ""}, - {"Exit.mnemonic", "", "", "", ""}, - {"expand", "", "", "", ""}, - {"Fail to load plugin", "", "", "", ""}, - {"FileChooser.fileExists.cancelOption", "", "", "", ""}, - {"FileChooser.fileExists.message", "PhonyFileName", "", "", ""}, - {"FileChooser.fileExists.okOption", "", "", "", ""}, - {"FileChooser.fileExists.title", "", "", "", ""}, - {"FileChooser.savedFile", "PhonyFilePath", "PhonyFileSize", "", ""}, - {"FileChooser.saveFailed.message", "PhonyFilePath", "PhonyMessage", "", ""}, - {"FileChooser.saveFailed.title", "", "", "", ""}, - {"Free physical memory", "", "", "", ""}, - {"Free swap space", "", "", "", ""}, - {"Garbage collector", "", "", "", ""}, - {"GC time", "", "", "", ""}, - {"GC time details", 54, "Phony", 11, ""}, - {"GcInfo", "Phony", -1, 768, ""}, - {"GcInfo", "Phony", 0, 768, ""}, - {"GcInfo", "Phony", 1, 768, ""}, - {"Heap", "", "", "", ""}, - {"Heap Memory Usage", "", "", "", ""}, - {"Help.AboutDialog.accessibleDescription", "", "", "", ""}, - {"Help.AboutDialog.jConsoleVersion", "DummyVersion", "", "", ""}, - {"Help.AboutDialog.javaVersion", "DummyVersion", "", "", ""}, - {"Help.AboutDialog.masthead.accessibleName", "", "", "", ""}, - {"Help.AboutDialog.masthead.title", "", "", "", ""}, - {"Help.AboutDialog.title", "", "", "", ""}, - {"Help.AboutDialog.userGuideLink", "DummyMessage", "", "", ""}, - {"Help.AboutDialog.userGuideLink.mnemonic", "", "", "", ""}, - {"Help.AboutDialog.userGuideLink.url", "DummyURL", "", "", ""}, - {"HelpMenu.About.title", "", "", "", ""}, - {"HelpMenu.About.title.mnemonic", "", "", "", ""}, - {"HelpMenu.UserGuide.title", "", "", "", ""}, - {"HelpMenu.UserGuide.title.mnemonic", "", "", "", ""}, - {"HelpMenu.title", "", "", "", ""}, - {"HelpMenu.title.mnemonic", "", "", "", ""}, - {"Hotspot MBeans...", "", "", "", ""}, - {"Hotspot MBeans....mnemonic", "", "", "", ""}, - {"Hotspot MBeans.dialog.accessibleDescription", "", "", "", ""}, - {"Impact", "", "", "", ""}, - {"Info", "", "", "", ""}, - {"INFO", "", "", "", ""}, - {"Invalid plugin path", "", "", "", ""}, - {"Invalid URL", "", "", "", ""}, - {"Is", "", "", "", ""}, - {"Java Monitoring & Management Console", "", "", "", ""}, - {"Java Virtual Machine", "", "", "", ""}, - {"JConsole: ", "", "", "", ""}, - {"JConsole.accessibleDescription", "", "", "", ""}, - {"JConsole version", "PhonyVersion", "", "", ""}, - {"JIT compiler", "", "", "", ""}, - {"Library path", "", "", "", ""}, - {"Live Threads", "", "", "", ""}, - {"Loaded", "", "", "", ""}, - {"Local Process:", "", "", "", ""}, - {"Local Process:.mnemonic", "", "", "", ""}, - {"Manage Hotspot MBeans in: ", "", "", "", ""}, - {"Management Not Enabled", "", "", "", ""}, - {"Management Will Be Enabled", "", "", "", ""}, - {"Masthead.font", "", "", "", ""}, - {"Max", "", "", "", ""}, - {"Max", "", "", "", ""}, - {"Maximum heap size", "", "", "", ""}, - {"MBeanAttributeInfo", "", "", "", ""}, - {"MBeanInfo", "", "", "", ""}, - {"MBeanNotificationInfo", "", "", "", ""}, - {"MBeanOperationInfo", "", "", "", ""}, - {"MBeans", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.clearNotificationsButton.toolTip", "", "", "", ""}, - {"MBeansTab.compositeNavigationMultiple", 0, 0, "", ""}, - {"MBeansTab.compositeNavigationSingle", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton.mnemonic", "", "", "", ""}, - {"MBeansTab.refreshAttributesButton.toolTip", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.subscribeNotificationsButton.toolTip", "", "", "", ""}, - {"MBeansTab.tabularNavigationMultiple", 0, 0, "", ""}, - {"MBeansTab.tabularNavigationSingle", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton.mnemonic", "", "", "", ""}, - {"MBeansTab.unsubscribeNotificationsButton.toolTip", "", "", "", ""}, - {"Memory", "", "", "", ""}, - {"MemoryPoolLabel", "PhonyMemoryPool", "", "", ""}, - {"MemoryTab.heapPlotter.accessibleName", "", "", "", ""}, - {"MemoryTab.infoLabelFormat", "UsedCount", "CommittedCount", "MaxCount", ""}, - {"MemoryTab.nonHeapPlotter.accessibleName", "", "", "", ""}, - {"MemoryTab.poolChart.aboveThreshold", "Threshold", "", "", ""}, - {"MemoryTab.poolChart.accessibleName", "", "", "", ""}, - {"MemoryTab.poolChart.belowThreshold", "Threshold", "", "", ""}, - {"MemoryTab.poolPlotter.accessibleName", "PhonyMemoryPool", "", "", ""}, - {"Message", "", "", "", ""}, - {"Method successfully invoked", "", "", "", ""}, - {"Monitor locked", "", "", "", ""}, - {"Minimize All", "", "", "", ""}, - {"Minimize All.mnemonic", "", "", "", ""}, - {"Name", "", "", "", ""}, - {"Name and Build", "PhonyName", "PhonyBuild", "", ""}, - {"Name Build and Mode", "PhonyName", "PhonyBuild", "PhonyMode", ""}, - {"Name State", "PhonyName", "PhonyState", "", ""}, - {"Name State LockName", "PhonyName", "PhonyState", "PhonyLock", ""}, - {"Name State LockName LockOwner", "PhonyName", "PhonyState", "PhonyLock", "PhonyOwner"}, - {"New Connection...", "", "", "", ""}, - {"New Connection....mnemonic", "", "", "", ""}, - {"No deadlock detected", "", "", "", ""}, - {"Non-Heap", "", "", "", ""}, - {"Non-Heap Memory Usage", "", "", "", ""}, - {"Notification", "", "", "", ""}, - {"Notification buffer", "", "", "", ""}, - {"Notifications", "", "", "", ""}, - {"NotifTypes", "", "", "", ""}, - {"Number of Loaded Classes", "", "", "", ""}, - {"Number of processors", "", "", "", ""}, - {"Number of Threads", "", "", "", ""}, - {"ObjectName", "", "", "", ""}, - {"Operating System", "", "", "", ""}, - {"Operation", "", "", "", ""}, - {"Operation invocation", "", "", "", ""}, - {"Operation return value", "", "", "", ""}, - {"Operations", "", "", "", ""}, - {"Overview", "", "", "", ""}, - {"OverviewPanel.plotter.accessibleName", "PhonyPlotter", "", "", ""}, - {"Parameter", "", "", "", ""}, - {"Password: ", "", "", "", ""}, - {"Password: .mnemonic", "", "", "", ""}, - {"Password.accessibleName", "", "", "", ""}, - {"Peak", "", "", "", ""}, - {"Perform GC", "", "", "", ""}, - {"Perform GC.mnemonic", "", "", "", ""}, - {"Perform GC.toolTip", "", "", "", ""}, - {"Plotter.accessibleName", "", "", "", ""}, - {"Plotter.accessibleName.keyAndValue", "Key", "Value", "", ""}, - {"Plotter.accessibleName.noData", "", "", "", ""}, - {"Plotter.saveAsMenuItem", "", "", "", ""}, - {"Plotter.saveAsMenuItem.mnemonic", "", "", "", ""}, - {"Plotter.timeRangeMenu", "", "", "", ""}, - {"Plotter.timeRangeMenu.mnemonic", "", "", "", ""}, - {"plot", "", "", "", ""}, - {"Problem adding listener", "", "", "", ""}, - {"Problem displaying MBean", "", "", "", ""}, - {"Problem invoking", "", "", "", ""}, - {"Problem removing listener", "", "", "", ""}, - {"Problem setting attribute", "", "", "", ""}, - {"Process CPU time", "", "", "", ""}, - {"Readable", "", "", "", ""}, - {"Reconnect", "", "", "", ""}, - {"Remote Process:", "", "", "", ""}, - {"Remote Process:.mnemonic", "", "", "", ""}, - {"Remote Process.textField.accessibleName", "", "", "", ""}, - {"remoteTF.usage", "", "", "", ""}, - {"Restore All", "", "", "", ""}, - {"Restore All.mnemonic", "", "", "", ""}, - {"ReturnType", "", "", "", ""}, - {"SeqNum", "", "", "", ""}, - {"Size Bytes", 512, "", "", ""}, - {"Size Gb", 512, "", "", ""}, - {"Size Kb", 512, "", "", ""}, - {"Size Mb", 512, "", "", ""}, - {"Source", "", "", "", ""}, - {"Stack trace", "", "", "", ""}, - {"SummaryTab.headerDateTimeFormat", "", "", "", ""}, - {"SummaryTab.pendingFinalization.label", "", "", "", ""}, - {"SummaryTab.pendingFinalization.value", "ObjectCount", "", "", ""}, - {"SummaryTab.tabName", "", "", "", ""}, - {"SummaryTab.vmVersion", "VMName", "VMVersion", "", ""}, - {"ThreadTab.infoLabelFormat", "LiveCount", "PeakCount", "TotalCount", ""}, - {"ThreadTab.threadInfo.accessibleName", "", "", "", ""}, - {"ThreadTab.threadPlotter.accessibleName", "", "", "", ""}, - {"Threads", "", "", "", ""}, - {"Threshold", "", "", "", ""}, - {"Tile", "", "", "", ""}, - {"Tile.mnemonic", "", "", "", ""}, - {"Time", "", "", "", ""}, - {"Time Range:", "", "", "", ""}, - {"Time Range:.mnemonic", "", "", "", ""}, - {"TimeStamp", "", "", "", ""}, - {"Total classes loaded", "", "", "", ""}, - {"Total classes unloaded", "", "", "", ""}, - {"Total compile time", "", "", "", ""}, - {"Total Loaded", "", "", "", ""}, - {"Total physical memory", "", "", "", ""}, - {"Total swap space", "", "", "", ""}, - {"Total threads started", "", "", "", ""}, - {"Type", "", "", "", ""}, - {"Unavailable", "", "", "", ""}, - {"UNKNOWN", "", "", "", ""}, - {"Unregister", "", "", "", ""}, - {"Uptime", "", "", "", ""}, - {"Usage Threshold", "", "", "", ""}, - {"Used", "", "", "", ""}, - {"Username: ", "", "", "", ""}, - {"Username: .mnemonic", "", "", "", ""}, - {"Username.accessibleName", "", "", "", ""}, - {"UserData", "", "", "", ""}, - {"Value", "", "", "", ""}, - {"Vendor", "", "", "", ""}, - {"Verbose Output", "", "", "", ""}, - {"Verbose Output.toolTip", "", "", "", ""}, - {"visualize", "", "", "", ""}, - {"VM", "", "", "", ""}, - {"VMInternalFrame.accessibleDescription", "", "", "", ""}, - {"VM arguments", "", "", "", ""}, - {"Virtual Machine", "", "", "", ""}, - {"Window", "", "", "", ""}, - {"Window.mnemonic", "", "", "", ""}, - {"Writable", "", "", "", ""}, - {"zz usage text", "PhonyName", "", "", ""}, - }; - //boolean verbose = false; - boolean verbose = true; - - long badLookups = 0; - System.out.println("Start..."); - for (int ii = 0; ii < testData.length; ii++) { - String key = (String)testData[ii][0]; - - if (key.endsWith(".mnemonic")) { - String baseKey = key.substring(0, key.length() - ".mnemonic".length()); - int mnemonic = Resources.getMnemonicInt(baseKey); - if (mnemonic == 0) { - badLookups++; - System.out.println("****lookup failed for key = " + key); + public static void main(String... args) { + List errors = new ArrayList<>(); + // Ensure that all Message fields have a corresponding key/value + // in the resource bundle and that mnemonics can be looked + // up where applicable. + ResourceBundle rb = ResourceBundle.getBundle(RESOURCE_BUNDLE); + for (Field field : Messages.class.getFields()) { + if (isResourceKeyField(field)) { + String resourceKey = field.getName(); + String message = readField(field); + if (message.startsWith(MISSING_RESOURCE_KEY_PREFIX)) { + errors.add("Can't find message (and perhaps mnemonic) for " + + Messages.class.getSimpleName() + "." + + resourceKey + " in resource bundle."); } else { - if (verbose) { - System.out.println(" mnemonic: " + KeyEvent.getKeyText(mnemonic)); + String resourceMessage = rb.getString(resourceKey); + if (hasMnemonicIdentifier(resourceMessage)) { + int mi = Resources.getMnemonicInt(message); + if (mi == 0) { + errors.add("Could not look up mnemonic for message '" + + message + "'."); + } } } - continue; } + } - String ss = Resources.getText(key, - testData[ii][1], - testData[ii][2], - testData[ii][3], - testData[ii][4]); - if (ss.startsWith("missing resource key")) { - badLookups++; - System.out.println("****lookup failed for key = " + key); - } else { - if (verbose) { - System.out.println(" " + ss); + // Ensure that there is Message class field for every resource key. + for (String key : Collections.list(rb.getKeys())) { + try { + Messages.class.getField(key); + } catch (NoSuchFieldException nfe) { + errors.add("Can't find static field (" + + Messages.class.getSimpleName() + "." + key + + ") matching '" + key + + "' in resource bundle. Unused message?"); + } + } + + if (errors.size() > 0) { + throwError(errors); + } + } + + private static String readField(Field field) { + try { + return (String) field.get(null); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new Error("Could not access field " + field.getName() + + " when trying to read resource message."); + } + } + + private static boolean isResourceKeyField(Field field) { + int modifiers = field.getModifiers(); + return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers); + } + + private static boolean hasMnemonicIdentifier(String s) { + for (int i = 0; i < s.length() - 1; i++) { + if (s.charAt(i) == '&') { + if (s.charAt(i + 1) != '&') { + return true; + } else { + i++; } } } - if (badLookups > 0) { - throw new Error ("Resource lookup failed " + badLookups + - " time(s); Test failed"); + return false; + } + + private static void throwError(List errors) { + StringBuffer buffer = new StringBuffer(); + buffer.append("Found "); + buffer.append(errors.size()); + buffer.append(" error(s) when checking one-to-one mapping "); + buffer.append("between Message and resource bundle keys in "); + buffer.append(RESOURCE_BUNDLE); + buffer.append(" with "); + buffer.append(Locale.getDefault()); + buffer.append(" locale."); + buffer.append(NEW_LINE); + int errorIndex = 1; + for (String error : errors) { + buffer.append("Error "); + buffer.append(errorIndex); + buffer.append(": "); + buffer.append(error); + buffer.append(NEW_LINE); + errorIndex++; } - System.out.println("...Finished."); + throw new Error(buffer.toString()); } } diff --git a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh index bec63a7992f..01c2e4b6f01 100644 --- a/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh +++ b/jdk/test/sun/tools/jconsole/ResourceCheckTest.sh @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ pass() OS=`uname -s` case "$OS" in - SunOS | Linux ) + SunOS | Linux | Darwin) PATHSEP=":" ;; diff --git a/jdk/test/sun/util/locale/provider/Bug8024141.java b/jdk/test/sun/util/locale/provider/Bug8024141.java new file mode 100644 index 00000000000..24bd0f3024a --- /dev/null +++ b/jdk/test/sun/util/locale/provider/Bug8024141.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8024141 + * @summary Test for cache support of sun.util.locale.provider.LocaleResources.getTimeZoneNames + */ + +import java.time.ZoneId; +import static java.util.Locale.ENGLISH; +import static java.time.format.TextStyle.FULL; +import static java.time.format.TextStyle.SHORT; + +public class Bug8024141 { + // This test assumes that the two time zones are in GMT. If + // they become different zones, need to pick up another zones. + private static final String[] ZONES = { + "Africa/Abidjan", + "Africa/Bamako" + }; + + public static void main(String[] args) { + ZoneId gmt = ZoneId.of("GMT"); + String gmtName = gmt.getDisplayName(FULL, ENGLISH); + String gmtAbbr = gmt.getDisplayName(SHORT, ENGLISH); + + for (String zone : ZONES) { + ZoneId id = ZoneId.of(zone); + String name = id.getDisplayName(FULL, ENGLISH); + String abbr = id.getDisplayName(SHORT, ENGLISH); + + if (!name.equals(gmtName) || !abbr.equals(gmtAbbr)) { + throw new RuntimeException("inconsistent name/abbr for " + zone + ":\n" + + "name=" + name + ", abbr=" + abbr); + } + } + } +} diff --git a/make/scripts/webrev.ksh b/make/scripts/webrev.ksh index 9fef47fa69e..3839b7490f5 100644 --- a/make/scripts/webrev.ksh +++ b/make/scripts/webrev.ksh @@ -27,7 +27,7 @@ # Documentation is available via 'webrev -h'. # -WEBREV_UPDATED=24.0-hg+jbs +WEBREV_UPDATED=24.1-hg+openjdk.java.net HTML=' +# ' # JDK-1234567 my bugid' > .html # # framed_sdiff() is then called which creates $2.frames.html @@ -1476,7 +1476,7 @@ function treestatus # The first and last are simple addition while the middle one # is a move/rename or a copy. We can't distinguish from a rename vs a copy # without also getting the status of removed files. The middle case above - # is a rename if File4 is also shown a being removed. If File4 is not a + # is a rename if File4 is also shown a being removed. If File4 is not a # removed file, then the middle case is a copy from File4 to subdir/File4 # FIXME - we're not distinguishing copy from rename $HGCMD -aC | $FILTER | while read LINE; do @@ -1644,7 +1644,7 @@ function flist_from_mercurial # The first and last are simple addition while the middle one # is a move/rename or a copy. We can't distinguish from a rename vs a copy # without also getting the status of removed files. The middle case above - # is a rename if File4 is also shown a being removed. If File4 is not a + # is a rename if File4 is also shown a being removed. If File4 is not a # removed file, then the middle case is a copy from File4 to subdir/File4 # FIXME - we're not distinguishing copy from rename @@ -2529,7 +2529,7 @@ print " Output to: $WDIR" # Bug IDs will be replaced by a URL. Order of precedence # is: default location, $WEBREV_BUGURL, the -O flag. # -BUGURL='https://jbs.oracle.com/bugs/browse/' +BUGURL='https://bugs.openjdk.java.net/browse/' [[ -n $WEBREV_BUGURL ]] && BUGURL="$WEBREV_BUGURL" if [[ -n "$Oflag" ]]; then CRID=`echo $CRID | sed -e 's/JDK-//'` @@ -3056,7 +3056,7 @@ if [[ -n $CRID ]]; then for id in $CRID do if [[ -z "$Oflag" ]]; then - #add "JDK-" to raw bug id for jbs links. + #add "JDK-" to raw bug id for openjdk.java.net links. id=`echo ${id} | sed 's/^\([0-9]\{5,\}\)$/JDK-\1/'` fi print "Bug id:" diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 0cc3a707a66..05fbb43822b 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -216,3 +216,4 @@ e966ff0a3ffef8a687eaf5a14167bb595b623d02 jdk8-b102 afc100513451d22f0b8135999d6eb52f36df3d36 jdk8-b104 f484bfb624dd06683cb33b524700a5dd4927a82b jdk8-b105 bf70cbd2c8369fd97ffdfcbe1a80dbc2797408ee jdk8-b106 +f35e1255024b66f7cf82517798f45f6e194e5567 jdk8-b107 diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index 9a31be88592..73644a6b523 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -230,6 +230,10 @@ + + + + @@ -238,6 +242,7 @@ + @@ -264,6 +269,13 @@ grant codeBase "file:/${basedir}/test/script/basic/*" { permission java.util.PropertyPermission "nashorn.test.*", "read"; }; +grant codeBase "file:/${basedir}/test/script/basic/parser/*" { + permission java.io.FilePermission "${basedir}/test/script/-", "read"; + permission java.io.FilePermission "$${user.dir}", "read"; + permission java.util.PropertyPermission "user.dir", "read"; + permission java.util.PropertyPermission "nashorn.test.*", "read"; +}; + grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" { permission java.util.PropertyPermission "java.security.policy", "read"; }; diff --git a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java index 4f3a8e88f93..53b5790ee3e 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/JSObject.java +++ b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java @@ -25,73 +25,210 @@ package jdk.nashorn.api.scripting; +import java.util.Collection; +import java.util.Collections; +import java.util.Set; + /** - * netscape.javascript.JSObject-like interface for nashorn script objects. + * This is the base class for nashorn ScriptObjectMirror class. + * + * This class can also be subclassed by an arbitrary Java class. Nashorn will + * treat objects of such classes just like nashorn script objects. Usual nashorn + * operations like obj[i], obj.foo, obj.func(), delete obj.foo will be glued + * to appropriate method call of this class. */ public abstract class JSObject { /** - * Call a JavaScript function + * Call this object as a JavaScript function. This is equivalent to + * 'func.apply(thiz, args)' in JavaScript. * - * @param functionName name of function + * @param thiz 'this' object to be passed to the function * @param args arguments to method * @return result of call */ - public abstract Object call(String functionName, Object... args); + public Object call(Object thiz, Object... args) { + throw new UnsupportedOperationException("call"); + } /** - * Call a JavaScript method as a constructor. This is equivalent to - * calling new obj.Method(arg1, arg2...) in JavaScript. + * Call this 'constructor' JavaScript function to create a new object. + * This is equivalent to 'new func(arg1, arg2...)' in JavaScript. * - * @param functionName name of function * @param args arguments to method * @return result of constructor call */ - public abstract Object newObject(String functionName, Object... args); + public Object newObject(Object... args) { + throw new UnsupportedOperationException("newObject"); + } /** - * Evaluate a JavaScript expression + * Evaluate a JavaScript expression. * * @param s JavaScript expression to evaluate * @return evaluation result */ - public abstract Object eval(String s); + public Object eval(String s) { + throw new UnsupportedOperationException("eval"); + } /** - * Retrieves a named member of a JavaScript object. + * Call a JavaScript function member of this object. + * + * @param name name of the member function to call + * @param args arguments to be passed to the member function + * @return result of call + */ + public Object callMember(String name, Object... args) { + throw new UnsupportedOperationException("call"); + } + + /** + * Retrieves a named member of this JavaScript object. * * @param name of member * @return member */ - public abstract Object getMember(String name); + public Object getMember(String name) { + return null; + } /** - * Retrieves an indexed member of a JavaScript object. + * Retrieves an indexed member of this JavaScript object. * - * @param index index of member slot + * @param index index slot to retrieve * @return member */ - public abstract Object getSlot(int index); + public Object getSlot(int index) { + return null; + } /** - * Remove a named member from a JavaScript object + * Does this object have a named member? * * @param name name of member + * @return true if this object has a member of the given name */ - public abstract void removeMember(String name); + public boolean hasMember(String name) { + return false; + } /** - * Set a named member in a JavaScript object + * Does this object have a indexed property? * - * @param name name of member - * @param value value of member + * @param slot index to check + * @return true if this object has a slot */ - public abstract void setMember(String name, Object value); + public boolean hasSlot(int slot) { + return false; + } /** - * Set an indexed member in a JavaScript object + * Remove a named member from this JavaScript object * - * @param index index of member slot - * @param value value of member + * @param name name of the member */ - public abstract void setSlot(int index, Object value); + public void removeMember(String name) { + } + + /** + * Set a named member in this JavaScript object + * + * @param name name of the member + * @param value value of the member + */ + public void setMember(String name, Object value) { + } + + /** + * Set an indexed member in this JavaScript object + * + * @param index index of the member slot + * @param value value of the member + */ + public void setSlot(int index, Object value) { + } + + // property and value iteration + + /** + * Returns the set of all property names of this object. + * + * @return set of property names + */ + @SuppressWarnings("unchecked") + public Set keySet() { + return Collections.EMPTY_SET; + } + + /** + * Returns the set of all property values of this object. + * + * @return set of property values. + */ + @SuppressWarnings("unchecked") + public Collection values() { + return Collections.EMPTY_SET; + } + + // JavaScript instanceof check + + /** + * Checking whether the given object is an instance of 'this' object. + * + * @param instance instace to check + * @return true if the given 'instance' is an instance of this 'function' object + */ + public boolean isInstance(final Object instance) { + return false; + } + + /** + * Checking whether this object is an instance of the given 'clazz' object. + * + * @param clazz clazz to check + * @return true if this object is an instance of the given 'clazz' + */ + public boolean isInstanceOf(final Object clazz) { + if (clazz instanceof JSObject) { + return ((JSObject)clazz).isInstance(this); + } + + return false; + } + + /** + * ECMA [[Class]] property + * + * @return ECMA [[Class]] property value of this object + */ + public String getClassName() { + return getClass().getName(); + } + + /** + * Is this a function object? + * + * @return if this mirror wraps a ECMAScript function instance + */ + public boolean isFunction() { + return false; + } + + /** + * Is this a 'use strict' function object? + * + * @return true if this mirror represents a ECMAScript 'use strict' function + */ + public boolean isStrictFunction() { + return false; + } + + /** + * Is this an array object? + * + * @return if this mirror wraps a ECMAScript array object + */ + public boolean isArray() { + return false; + } } diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 9745d432783..45eddd117aa 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -315,7 +315,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C final ScriptObjectMirror mirror = (ScriptObjectMirror)thiz; realSelf = mirror.getScriptObject(); realGlobal = mirror.getHomeGlobal(); - if (! realGlobal.isOfContext(nashornContext)) { + if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } else if (thiz instanceof ScriptObject) { @@ -326,7 +326,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); } - if (! realGlobal.isOfContext(nashornContext)) { + if (! isOfContext(realGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } @@ -394,7 +394,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C // Retrieve nashorn Global object from a given ScriptObjectMirror private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) { ScriptObject sobj = mirror.getScriptObject(); - if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) { + if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) { return sobj; } @@ -470,7 +470,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C ScriptObjectMirror selfMirror = null; if (selfObject instanceof ScriptObjectMirror) { selfMirror = (ScriptObjectMirror)selfObject; - if (! selfMirror.getHomeGlobal().isOfContext(nashornContext)) { + if (! isOfContext(selfMirror.getHomeGlobal(), nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } } else if (selfObject instanceof ScriptObject) { @@ -481,7 +481,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C throw new IllegalArgumentException(getMessage("no.current.nashorn.global")); } - if (! oldGlobal.isOfContext(nashornContext)) { + if (! isOfContext(oldGlobal, nashornContext)) { throw new IllegalArgumentException(getMessage("script.object.from.another.engine")); } @@ -494,7 +494,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C if (selfMirror != null) { try { - return ScriptObjectMirror.translateUndefined(selfMirror.call(name, args)); + return ScriptObjectMirror.translateUndefined(selfMirror.callMember(name, args)); } catch (final Exception e) { final Throwable cause = e.getCause(); if (cause instanceof NoSuchMethodException) { @@ -617,4 +617,9 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } return true; } + + private static boolean isOfContext(final ScriptObject global, final Context context) { + assert global instanceof GlobalObject: "Not a Global object"; + return ((GlobalObject)global).isOfContext(context); + } } diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java index 99ce73c1ca1..3a27d23e303 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java @@ -42,14 +42,13 @@ import java.util.Set; import java.util.concurrent.Callable; import javax.script.Bindings; import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.GlobalObject; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; /** - * Mirror object that wraps a given ScriptObject instance. User can - * access ScriptObject via the javax.script.Bindings interface or - * netscape.javascript.JSObject interface. + * Mirror object that wraps a given Nashorn Script object. */ public final class ScriptObjectMirror extends JSObject implements Bindings { private static AccessControlContext getContextAccCtxt() { @@ -62,6 +61,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { private final ScriptObject sobj; private final ScriptObject global; + private final boolean strict; @Override public boolean equals(final Object other) { @@ -88,8 +88,9 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { } // JSObject methods + @Override - public Object call(final String functionName, final Object... args) { + public Object call(final Object thiz, final Object... args) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); @@ -98,15 +99,13 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { Context.setGlobal(global); } - final Object val = functionName == null? sobj : sobj.get(functionName); - if (val instanceof ScriptFunction) { + if (sobj instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); - } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { - return ((ScriptObjectMirror)val).call(null, args); + final Object self = globalChanged? wrap(thiz, oldGlobal) : thiz; + return wrap(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)), global); } - throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : "")); + throw new RuntimeException("not a function: " + toString()); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { @@ -119,7 +118,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { } @Override - public Object newObject(final String functionName, final Object... args) { + public Object newObject(final Object... args) { final ScriptObject oldGlobal = Context.getGlobal(); final boolean globalChanged = (oldGlobal != global); @@ -128,15 +127,12 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { Context.setGlobal(global); } - final Object val = functionName == null? sobj : sobj.get(functionName); - if (val instanceof ScriptFunction) { + if (sobj instanceof ScriptFunction) { final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; - return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global); - } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { - return ((ScriptObjectMirror)val).newObject(null, args); + return wrap(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)), global); } - throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : "")); + throw new RuntimeException("not a constructor: " + toString()); } catch (final RuntimeException | Error e) { throw e; } catch (final Throwable t) { @@ -165,8 +161,40 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public Object callMember(final String functionName, final Object... args) { + functionName.getClass(); // null check + final ScriptObject oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + + try { + if (globalChanged) { + Context.setGlobal(global); + } + + final Object val = sobj.get(functionName); + if (val instanceof ScriptFunction) { + final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; + return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); + } else if (val instanceof JSObject && ((JSObject)val).isFunction()) { + return ((JSObject)val).call(sobj, args); + } + + throw new NoSuchMethodException("No such function " + functionName); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } finally { + if (globalChanged) { + Context.setGlobal(oldGlobal); + } + } + } + @Override public Object getMember(final String name) { + name.getClass(); return inGlobal(new Callable() { @Override public Object call() { return wrap(sobj.get(name), global); @@ -183,13 +211,34 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } + @Override + public boolean hasMember(final String name) { + name.getClass(); + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.has(name); + } + }); + } + + @Override + public boolean hasSlot(final int slot) { + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.has(slot); + } + }); + } + @Override public void removeMember(final String name) { + name.getClass(); remove(name); } @Override public void setMember(final String name, final Object value) { + name.getClass(); put(name, value); } @@ -197,19 +246,58 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public void setSlot(final int index, final Object value) { inGlobal(new Callable() { @Override public Void call() { - sobj.set(index, unwrap(value, global), global.isStrictContext()); + sobj.set(index, unwrap(value, global), strict); return null; } }); } + @Override + public boolean isInstance(final Object obj) { + if (! (obj instanceof ScriptObjectMirror)) { + return false; + } + + final ScriptObjectMirror instance = (ScriptObjectMirror)obj; + // if not belongs to my global scope, return false + if (global != instance.global) { + return false; + } + + return inGlobal(new Callable() { + @Override public Boolean call() { + return sobj.isInstance(instance.sobj); + } + }); + } + + @Override + public String getClassName() { + return sobj.getClassName(); + } + + @Override + public boolean isFunction() { + return sobj instanceof ScriptFunction; + } + + @Override + public boolean isStrictFunction() { + return isFunction() && ((ScriptFunction)sobj).isStrict(); + } + + @Override + public boolean isArray() { + return sobj.isArray(); + } + // javax.script.Bindings methods @Override public void clear() { inGlobal(new Callable() { @Override public Object call() { - sobj.clear(); + sobj.clear(strict); return null; } }); @@ -292,7 +380,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { return inGlobal(new Callable() { @Override public Object call() { final Object modValue = globalChanged? wrap(value, oldGlobal) : value; - return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global)), global)); + return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global), strict), global)); } }); } @@ -303,7 +391,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { final boolean globalChanged = (oldGlobal != global); inGlobal(new Callable() { @Override public Object call() { - final boolean strict = global.isStrictContext(); for (final Map.Entry entry : map.entrySet()) { final Object value = entry.getValue(); final Object modValue = globalChanged? wrap(value, oldGlobal) : value; @@ -318,7 +405,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public Object remove(final Object key) { return inGlobal(new Callable() { @Override public Object call() { - return wrap(sobj.remove(unwrap(key, global)), global); + return wrap(sobj.remove(unwrap(key, global), strict), global); } }); } @@ -333,7 +420,7 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { public boolean delete(final Object key) { return inGlobal(new Callable() { @Override public Boolean call() { - return sobj.delete(unwrap(key, global)); + return sobj.delete(unwrap(key, global), strict); } }); } @@ -390,15 +477,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } - /** - * ECMA [[Class]] property - * - * @return ECMA [[Class]] property value of this object - */ - public String getClassName() { - return sobj.getClassName(); - } - /** * ECMA 8.12.1 [[GetOwnProperty]] (P) * @@ -505,55 +583,6 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { }); } - // ECMAScript instanceof check - - /** - * Checking whether a script object is an instance of another by - * walking the proto chain - * - * @param instance instace to check - * @return true if 'instance' is an instance of this object - */ - public boolean isInstance(final ScriptObjectMirror instance) { - // if not belongs to my global scope, return false - if (instance == null || global != instance.global) { - return false; - } - - return inGlobal(new Callable() { - @Override public Boolean call() { - return sobj.isInstance(instance.sobj); - } - }); - } - - /** - * is this a function object? - * - * @return if this mirror wraps a ECMAScript function instance - */ - public boolean isFunction() { - return sobj instanceof ScriptFunction; - } - - /** - * is this a 'use strict' function object? - * - * @return true if this mirror represents a ECMAScript 'use strict' function - */ - public boolean isStrictFunction() { - return isFunction() && ((ScriptFunction)sobj).isStrict(); - } - - /** - * is this an array object? - * - * @return if this mirror wraps a ECMAScript array object - */ - public boolean isArray() { - return sobj.isArray(); - } - /** * Utility to check if given object is ECMAScript undefined value * @@ -637,10 +666,11 @@ public final class ScriptObjectMirror extends JSObject implements Bindings { ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) { assert sobj != null : "ScriptObjectMirror on null!"; - assert global != null : "null global for ScriptObjectMirror!"; + assert global instanceof GlobalObject : "global is not a GlobalObject"; this.sobj = sobj; this.global = global; + this.strict = ((GlobalObject)global).isStrictContext(); } // accessors for script engine diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 294300626d2..813d3fc9083 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -26,6 +26,7 @@ package jdk.nashorn.internal.codegen; import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; +import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS_VAR; import static jdk.nashorn.internal.codegen.CompilerConstants.CALLEE; import static jdk.nashorn.internal.codegen.CompilerConstants.EXCEPTION_PREFIX; import static jdk.nashorn.internal.codegen.CompilerConstants.ITERATOR_PREFIX; @@ -172,7 +173,9 @@ final class Attr extends NodeOperatorVisitor { initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL); if (functionNode.needsArguments()) { initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED); - addLocalDef(ARGUMENTS.symbolName()); + final String argumentsName = ARGUMENTS_VAR.symbolName(); + newType(defineSymbol(body, argumentsName, IS_VAR | IS_ALWAYS_DEFINED), Type.typeFor(ARGUMENTS_VAR.type())); + addLocalDef(argumentsName); } } @@ -491,30 +494,29 @@ final class Attr extends NodeOperatorVisitor { objectifySymbols(body); } + List syntheticInitializers = null; + if (body.getFlag(Block.NEEDS_SELF_SYMBOL)) { - final IdentNode callee = compilerConstant(CALLEE); - VarNode selfInit = - new VarNode( - newFunctionNode.getLineNumber(), - newFunctionNode.getToken(), - newFunctionNode.getFinish(), - newFunctionNode.getIdent(), - callee); + syntheticInitializers = new ArrayList<>(2); + LOG.info("Accepting self symbol init for ", newFunctionNode.getName()); + // "var fn = :callee" + syntheticInitializers.add(createSyntheticInitializer(newFunctionNode.getIdent(), CALLEE, newFunctionNode)); + } - LOG.info("Accepting self symbol init ", selfInit, " for ", newFunctionNode.getName()); + if(newFunctionNode.needsArguments()) { + if(syntheticInitializers == null) { + syntheticInitializers = new ArrayList<>(1); + } + // "var arguments = :arguments" + syntheticInitializers.add(createSyntheticInitializer(createImplicitIdentifier(ARGUMENTS_VAR.symbolName()), + ARGUMENTS, newFunctionNode)); + } - final List newStatements = new ArrayList<>(); - assert callee.getSymbol() != null && callee.getSymbol().hasSlot(); - - final IdentNode name = selfInit.getName(); - final Symbol nameSymbol = body.getExistingSymbol(name.getName()); - - assert nameSymbol != null; - - selfInit = selfInit.setName((IdentNode)name.setSymbol(lc, nameSymbol)); - - newStatements.add(selfInit); - newStatements.addAll(body.getStatements()); + if(syntheticInitializers != null) { + final List stmts = body.getStatements(); + final List newStatements = new ArrayList<>(stmts.size() + syntheticInitializers.size()); + newStatements.addAll(syntheticInitializers); + newStatements.addAll(stmts); newFunctionNode = newFunctionNode.setBody(lc, body.setStatements(lc, newStatements)); } @@ -533,6 +535,28 @@ final class Attr extends NodeOperatorVisitor { return newFunctionNode; } + /** + * Creates a synthetic initializer for a variable (a var statement that doesn't occur in the source code). Typically + * used to create assignmnent of {@code :callee} to the function name symbol in self-referential function + * expressions as well as for assignment of {@code :arguments} to {@code arguments}. + * + * @param name the ident node identifying the variable to initialize + * @param initConstant the compiler constant it is initialized to + * @param fn the function node the assignment is for + * @return a var node with the appropriate assignment + */ + private VarNode createSyntheticInitializer(final IdentNode name, final CompilerConstants initConstant, final FunctionNode fn) { + final IdentNode init = compilerConstant(initConstant); + assert init.getSymbol() != null && init.getSymbol().hasSlot(); + + VarNode synthVar = new VarNode(fn.getLineNumber(), fn.getToken(), fn.getFinish(), name, init); + + final Symbol nameSymbol = fn.getBody().getExistingSymbol(name.getName()); + assert nameSymbol != null; + + return synthVar.setName((IdentNode)name.setSymbol(lc, nameSymbol)); + } + @Override public Node leaveCONVERT(final UnaryNode unaryNode) { assert false : "There should be no convert operators in IR during Attribution"; @@ -886,10 +910,9 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveDECINC(final UnaryNode unaryNode) { // @see assignOffset - final UnaryNode newUnaryNode = unaryNode.setRHS(ensureAssignmentSlots(unaryNode.rhs())); final Type type = arithType(); - newType(newUnaryNode.rhs().getSymbol(), type); - return end(ensureSymbol(type, newUnaryNode)); + newType(unaryNode.rhs().getSymbol(), type); + return end(ensureSymbol(type, unaryNode)); } @Override @@ -975,15 +998,18 @@ final class Attr extends NodeOperatorVisitor { } private IdentNode compilerConstant(CompilerConstants cc) { - final FunctionNode functionNode = lc.getCurrentFunction(); - return (IdentNode) - new IdentNode( - functionNode.getToken(), - functionNode.getFinish(), - cc.symbolName()). - setSymbol( - lc, - functionNode.compilerConstant(cc)); + return (IdentNode)createImplicitIdentifier(cc.symbolName()).setSymbol(lc, lc.getCurrentFunction().compilerConstant(cc)); + } + + /** + * Creates an ident node for an implicit identifier within the function (one not declared in the script source + * code). These identifiers are defined with function's token and finish. + * @param name the name of the identifier + * @return an ident node representing the implicit identifier. + */ + private IdentNode createImplicitIdentifier(final String name) { + final FunctionNode fn = lc.getCurrentFunction(); + return new IdentNode(fn.getToken(), fn.getFinish(), name); } @Override @@ -1574,39 +1600,6 @@ final class Attr extends NodeOperatorVisitor { return newInternal(lc.getCurrentFunction().uniqueName(EXCEPTION_PREFIX.symbolName()), Type.typeFor(EXCEPTION_PREFIX.type())); } - /** - * In an assignment, recursively make sure that there are slots for - * everything that has to be laid out as temporary storage, which is the - * case if we are assign-op:ing a BaseNode subclass. This has to be - * recursive to handle things like multi dimensional arrays as lhs - * - * see NASHORN-258 - * - * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes - */ - private Expression ensureAssignmentSlots(final Expression assignmentDest) { - final LexicalContext attrLexicalContext = lc; - return (Expression)assignmentDest.accept(new NodeVisitor(new LexicalContext()) { - @Override - public Node leaveIndexNode(final IndexNode indexNode) { - assert indexNode.getSymbol().isTemp(); - final Expression index = indexNode.getIndex(); - //only temps can be set as needing slots. the others will self resolve - //it is illegal to take a scope var and force it to be a slot, that breaks - Symbol indexSymbol = index.getSymbol(); - if (indexSymbol.isTemp() && !indexSymbol.isConstant() && !indexSymbol.hasSlot()) { - if(indexSymbol.isShared()) { - indexSymbol = temporarySymbols.createUnshared(indexSymbol); - } - indexSymbol.setNeedsSlot(true); - attrLexicalContext.getCurrentBlock().putSymbol(attrLexicalContext, indexSymbol); - return indexNode.setIndex(index.setSymbol(attrLexicalContext, indexSymbol)); - } - return indexNode; - } - }); - } - /** * Return the type that arithmetic ops should use. Until we have implemented better type * analysis (range based) or overflow checks that are fast enough for int arithmetic, @@ -1704,7 +1697,7 @@ final class Attr extends NodeOperatorVisitor { newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType // ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine - return end(ensureSymbol(destType, ensureAssignmentSlots(binaryNode))); + return end(ensureSymbol(destType, binaryNode)); } private Expression ensureSymbol(final Type type, final Expression expr) { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 0ccc8a40489..809b2ec21e2 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -1361,6 +1361,7 @@ final class CodeGenerator extends NodeOperatorVisitor values = new ArrayList<>(); boolean hasGettersSetters = false; + Expression protoNode = null; for (PropertyNode propertyNode: elements) { final Expression value = propertyNode.getValue(); @@ -1369,6 +1370,9 @@ final class CodeGenerator extends NodeOperatorVisitor * * @return true if can have callsite type */ diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index be4d49b444a..dabc7e36bf1 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -27,6 +27,7 @@ package jdk.nashorn.internal.ir.debug; import java.util.Arrays; import java.util.List; +import java.util.ArrayList; import jdk.nashorn.internal.codegen.CompilerConstants; import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BinaryNode; @@ -197,10 +198,10 @@ public final class JSONWriter extends NodeVisitor { comma(); final IdentNode label = breakNode.getLabel(); + property("label"); if (label != null) { - property("label", label.getName()); + label.accept(this); } else { - property("label"); nullValue(); } @@ -256,13 +257,11 @@ public final class JSONWriter extends NodeVisitor { comma(); final Node guard = catchNode.getExceptionCondition(); - property("guard"); if (guard != null) { + property("guard"); guard.accept(this); - } else { - nullValue(); + comma(); } - comma(); property("body"); catchNode.getBody().accept(this); @@ -278,10 +277,10 @@ public final class JSONWriter extends NodeVisitor { comma(); final IdentNode label = continueNode.getLabel(); + property("label"); if (label != null) { - property("label", label.getName()); + label.accept(this); } else { - property("label"); nullValue(); } @@ -299,13 +298,20 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterExpressionStatement(final ExpressionStatement expressionStatement) { + // handle debugger statement + final Node expression = expressionStatement.getExpression(); + if (expression instanceof RuntimeNode) { + expression.accept(this); + return false; + } + enterDefault(expressionStatement); type("ExpressionStatement"); comma(); property("expression"); - expressionStatement.getExpression().accept(this); + expression.accept(this); return leave(); } @@ -388,13 +394,14 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterFunctionNode(final FunctionNode functionNode) { - enterDefault(functionNode); - final boolean program = functionNode.isProgram(); - final String name; if (program) { - name = "Program"; - } else if (functionNode.isDeclared()) { + return emitProgram(functionNode); + } + + enterDefault(functionNode); + final String name; + if (functionNode.isDeclared()) { name = "FunctionDeclaration"; } else { name = "FunctionExpression"; @@ -402,24 +409,41 @@ public final class JSONWriter extends NodeVisitor { type(name); comma(); - if (! program) { - property("id"); - if (functionNode.isAnonymous()) { - nullValue(); - } else { - functionNode.getIdent().accept(this); - } - comma(); + property("id"); + if (functionNode.isAnonymous()) { + nullValue(); + } else { + functionNode.getIdent().accept(this); } + comma(); + + array("params", functionNode.getParameters()); + comma(); + + arrayStart("defaults"); + arrayEnd(); + comma(); property("rest"); nullValue(); comma(); - if (!program) { - array("params", functionNode.getParameters()); - comma(); - } + property("body"); + functionNode.getBody().accept(this); + comma(); + + property("generator", false); + comma(); + + property("expression", false); + + return leave(); + } + + private boolean emitProgram(final FunctionNode functionNode) { + enterDefault(functionNode); + type("Program"); + comma(); // body consists of nested functions and statements final List stats = functionNode.getBody().getStatements(); @@ -730,7 +754,31 @@ public final class JSONWriter extends NodeVisitor { tryNode.getBody().accept(this); comma(); - array("handlers", tryNode.getCatches()); + + final List catches = tryNode.getCatches(); + final List guarded = new ArrayList<>(); + CatchNode unguarded = null; + if (catches != null) { + for (Node n : catches) { + CatchNode cn = (CatchNode)n; + if (cn.getExceptionCondition() != null) { + guarded.add(cn); + } else { + assert unguarded == null: "too many unguarded?"; + unguarded = cn; + } + } + } + + array("guardedHandlers", guarded); + comma(); + + property("handler"); + if (unguarded != null) { + unguarded.accept(this); + } else { + nullValue(); + } comma(); property("finalizer"); @@ -760,8 +808,8 @@ public final class JSONWriter extends NodeVisitor { array("arguments", callNode.getArgs()); } else { - final boolean prefix; final String operator; + final boolean prefix; switch (tokenType) { case INCPOSTFIX: prefix = false; @@ -780,8 +828,9 @@ public final class JSONWriter extends NodeVisitor { prefix = true; break; default: - prefix = false; + prefix = true; operator = tokenType.getName(); + break; } type(unaryNode.isAssignment()? "UpdateExpression" : "UnaryExpression"); @@ -802,6 +851,14 @@ public final class JSONWriter extends NodeVisitor { @Override public boolean enterVarNode(final VarNode varNode) { + final Node init = varNode.getInit(); + if (init instanceof FunctionNode && ((FunctionNode)init).isDeclared()) { + // function declaration - don't emit VariableDeclaration instead + // just emit FunctionDeclaration using 'init' Node. + init.accept(this); + return false; + } + enterDefault(varNode); type("VariableDeclaration"); @@ -816,11 +873,11 @@ public final class JSONWriter extends NodeVisitor { type("VariableDeclarator"); comma(); - property("id", varNode.getName().toString()); + property("id"); + varNode.getName().accept(this); comma(); property("init"); - final Node init = varNode.getInit(); if (init != null) { init.accept(this); } else { @@ -855,7 +912,7 @@ public final class JSONWriter extends NodeVisitor { whileNode.getTest().accept(this); comma(); - property("block"); + property("body"); whileNode.getBody().accept(this); } @@ -894,23 +951,27 @@ public final class JSONWriter extends NodeVisitor { return buf.toString(); } - private void property(final String key, final String value) { + private void property(final String key, final String value, final boolean escape) { buf.append('"'); buf.append(key); buf.append("\":"); if (value != null) { - buf.append('"'); + if (escape) buf.append('"'); buf.append(value); - buf.append('"'); + if (escape) buf.append('"'); } } + private void property(final String key, final String value) { + property(key, value, true); + } + private void property(final String key, final boolean value) { - property(key, Boolean.toString(value)); + property(key, Boolean.toString(value), false); } private void property(final String key, final int value) { - property(key, Integer.toString(value)); + property(key, Integer.toString(value), false); } private void property(final String key) { diff --git a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java index 4d8a2977e33..34fe2eb6a87 100644 --- a/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java +++ b/nashorn/src/jdk/nashorn/internal/lookup/MethodHandleFactory.java @@ -565,7 +565,7 @@ public final class MethodHandleFactory { @Override public MethodHandle asSpreader(final MethodHandle handle, final Class arrayType, final int arrayLength) { - final MethodHandle mh = super.asCollector(handle, arrayType, arrayLength); + final MethodHandle mh = super.asSpreader(handle, arrayType, arrayLength); return debug(mh, "asSpreader", handle, arrayType, arrayLength); } diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index 6d7be378be6..b7a902b745e 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -412,6 +412,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // initialized by nasgen private static PropertyMap $nasgenmap$; + // context to which this global belongs to + private final Context context; + + @Override + protected Context getContext() { + return context; + } + // performs initialization checks for Global constructor and returns the // PropertyMap, if everything is fine. private static PropertyMap checkAndGetMap(final Context context) { @@ -439,7 +447,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { */ public Global(final Context context) { super(checkAndGetMap(context)); - this.setContext(context); + this.context = context; this.setIsScope(); final int cacheSize = context.getEnv()._class_cache_size; @@ -481,6 +489,16 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // GlobalObject interface implementation + @Override + public boolean isOfContext(final Context context) { + return this.context == context; + } + + @Override + public boolean isStrictContext() { + return context.getEnv()._strict; + } + @Override public void initBuiltinObjects() { if (this.builtinObject != null) { @@ -1765,7 +1783,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // do not fill $ENV if we have a security manager around // Retrieve current state of ENV variables. final ScriptObject env = newObject(); - env.putAll(System.getenv()); + env.putAll(System.getenv(), scriptEnv._strict); addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, env); } else { addOwnProperty(ScriptingFunctions.ENV_NAME, Attribute.NOT_ENUMERABLE, UNDEFINED); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java index 54f293873ed..8cb1ded934c 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java @@ -41,7 +41,7 @@ import java.util.Iterator; import java.util.List; import java.util.concurrent.Callable; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -374,7 +374,7 @@ public final class NativeArray extends ScriptObject { public static Object isArray(final Object self, final Object arg) { return isArray(arg) || (arg == Global.instance().getArrayPrototype()) || (arg instanceof NativeRegExpExecResult) - || (arg instanceof ScriptObjectMirror && ((ScriptObjectMirror)arg).isArray()); + || (arg instanceof JSObject && ((JSObject)arg).isArray()); } /** diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java index c208a35ce7e..c77002e310b 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java @@ -30,7 +30,7 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.util.List; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; @@ -88,7 +88,7 @@ public final class NativeFunction { */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static Object apply(final Object self, final Object thiz, final Object array) { - if (!(self instanceof ScriptFunction)) { + if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) { throw typeError("not.a.function", ScriptRuntime.safeToString(self)); } @@ -111,21 +111,27 @@ public final class NativeFunction { list.toArray(args = new Object[list.size()]); } else if (array == null || array == UNDEFINED) { args = ScriptRuntime.EMPTY_ARRAY; - } else if (array instanceof ScriptObjectMirror) { - // look for array-like ScriptObjectMirror object - final ScriptObjectMirror mirror = (ScriptObjectMirror)array; - final Object len = mirror.containsKey("length")? mirror.getMember("length") : Integer.valueOf(0); + } else if (array instanceof JSObject) { + // look for array-like JSObject object + final JSObject jsObj = (JSObject)array; + final Object len = jsObj.hasMember("length")? jsObj.getMember("length") : Integer.valueOf(0); final int n = (int)JSType.toUint32(len); args = new Object[n]; for (int i = 0; i < args.length; i++) { - args[i] = mirror.containsKey(i)? mirror.getSlot(i) : UNDEFINED; + args[i] = jsObj.hasSlot(i)? jsObj.getSlot(i) : UNDEFINED; } } else { throw typeError("function.apply.expects.array"); } - return ScriptRuntime.apply((ScriptFunction)self, thiz, args); + if (self instanceof ScriptFunction) { + return ScriptRuntime.apply((ScriptFunction)self, thiz, args); + } else if (self instanceof JSObject) { + return ((JSObject)self).call(thiz, args); + } + + throw new AssertionError("should not reach here"); } /** @@ -137,7 +143,7 @@ public final class NativeFunction { */ @Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1) public static Object call(final Object self, final Object... args) { - if (!(self instanceof ScriptFunction)) { + if (!(self instanceof ScriptFunction) && !(self instanceof JSObject)) { throw typeError("not.a.function", ScriptRuntime.safeToString(self)); } @@ -151,7 +157,13 @@ public final class NativeFunction { arguments = ScriptRuntime.EMPTY_ARRAY; } - return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); + if (self instanceof ScriptFunction) { + return ScriptRuntime.apply((ScriptFunction)self, thiz, arguments); + } else if (self instanceof JSObject) { + return ((JSObject)self).call(thiz, arguments); + } + + throw new AssertionError("should not reach here"); } /** diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java index 011fd8bf84b..5e9ac83d5e1 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java @@ -34,6 +34,7 @@ import java.util.Deque; import java.util.List; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.support.TypeUtilities; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; @@ -43,6 +44,7 @@ import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ListAdapter; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory; @@ -288,7 +290,9 @@ public final class NativeJava { return null; } - Global.checkObject(obj); + if (!(obj instanceof ScriptObject) && !(obj instanceof JSObject)) { + throw typeError("not.an.object", ScriptRuntime.safeToString(obj)); + } final Class targetClass; if(objType == UNDEFINED) { @@ -304,11 +308,11 @@ public final class NativeJava { } if(targetClass.isArray()) { - return ((ScriptObject)obj).getArray().asArrayOfType(targetClass.getComponentType()); + return JSType.toJavaArray(obj, targetClass.getComponentType()); } if(targetClass == List.class || targetClass == Deque.class) { - return new ListAdapter((ScriptObject)obj); + return ListAdapter.create(obj); } throw typeError("unsupported.java.to.type", targetClass.getName()); diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index ab008900f50..d051917149e 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -25,7 +25,6 @@ package jdk.nashorn.internal.parser; -import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; import static jdk.nashorn.internal.codegen.CompilerConstants.EVAL; import static jdk.nashorn.internal.codegen.CompilerConstants.FUNCTION_PREFIX; import static jdk.nashorn.internal.codegen.CompilerConstants.RUN_SCRIPT; @@ -115,6 +114,8 @@ import jdk.nashorn.internal.runtime.Timing; * Builds the IR. */ public class Parser extends AbstractParser { + private static final String ARGUMENTS_NAME = CompilerConstants.ARGUMENTS_VAR.symbolName(); + /** Current script environment. */ private final ScriptEnvironment env; @@ -511,13 +512,19 @@ loop: * @param ident Referenced property. */ private void detectSpecialProperty(final IdentNode ident) { - final String name = ident.getName(); - - if (ARGUMENTS.symbolName().equals(name)) { + if (isArguments(ident)) { lc.setFlag(lc.getCurrentFunction(), FunctionNode.USES_ARGUMENTS); } } + private static boolean isArguments(final String name) { + return ARGUMENTS_NAME.equals(name); + } + + private static boolean isArguments(final IdentNode ident) { + return isArguments(ident.getName()); + } + /** * Tells whether a IdentNode can be used as L-value of an assignment * @@ -2060,7 +2067,7 @@ loop: case FLOATING: return getLiteral(); default: - return getIdentifierName(); + return getIdentifierName().setIsPropertyName(); } } @@ -2449,7 +2456,7 @@ loop: } else if (env._function_statement == ScriptEnvironment.FunctionStatementBehavior.WARNING) { warning(JSErrorType.SYNTAX_ERROR, AbstractParser.message("no.func.decl.here.warn"), functionToken); } - if (ARGUMENTS.symbolName().equals(name.getName())) { + if (isArguments(name)) { lc.setFlag(lc.getCurrentFunction(), FunctionNode.DEFINES_ARGUMENTS); } } @@ -2468,7 +2475,7 @@ loop: final IdentNode parameter = parameters.get(i); String parameterName = parameter.getName(); - if (ARGUMENTS.symbolName().equals(parameterName)) { + if (isArguments(parameterName)) { functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } @@ -2486,7 +2493,7 @@ loop: parametersSet.add(parameterName); } } else if (arity == 1) { - if (ARGUMENTS.symbolName().equals(parameters.get(0).getName())) { + if (isArguments(parameters.get(0))) { functionNode = functionNode.setFlag(lc, FunctionNode.DEFINES_ARGUMENTS); } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 2f0c95d89b9..7c69eb52035 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -236,6 +236,10 @@ public final class Context { private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; + /*package-private*/ ClassLoader getSharedLoader() { + return sharedLoader; + } + private static AccessControlContext createNoPermAccCtxt() { return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); } @@ -254,7 +258,7 @@ public final class Context { sharedLoader = AccessController.doPrivileged(new PrivilegedAction() { @Override public StructureLoader run() { - return new StructureLoader(myLoader, null); + return new StructureLoader(myLoader); } }, CREATE_LOADER_ACC_CTXT); } @@ -573,7 +577,7 @@ public final class Context { setGlobalTrusted(newGlobal); final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal); - newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped)); + newGlobal.put("arguments", ((GlobalObject)newGlobal).wrapAsObject(wrapped), env._strict); try { // wrap objects from newGlobal's world as mirrors - but if result @@ -599,7 +603,7 @@ public final class Context { * @throws ClassNotFoundException if structure class cannot be resolved */ public static Class forStructureClass(final String fullName) throws ClassNotFoundException { - if (System.getSecurityManager() != null && !NashornLoader.isStructureClass(fullName)) { + if (System.getSecurityManager() != null && !StructureLoader.isStructureClass(fullName)) { throw new ClassNotFoundException(fullName); } return Class.forName(fullName, true, sharedLoader); @@ -792,12 +796,11 @@ public final class Context { static Context fromClass(final Class clazz) { final ClassLoader loader = clazz.getClassLoader(); - Context context = null; - if (loader instanceof NashornLoader) { - context = ((NashornLoader)loader).getContext(); + if (loader instanceof ScriptLoader) { + return ((ScriptLoader)loader).getContext(); } - return (context != null) ? context : Context.getContextTrusted(); + return Context.getContextTrusted(); } private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { @@ -899,7 +902,7 @@ public final class Context { new PrivilegedAction() { @Override public ScriptLoader run() { - return new ScriptLoader(sharedLoader, Context.this); + return new ScriptLoader(appLoader, Context.this); } }, CREATE_LOADER_ACC_CTXT); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java index 5b608f4b37b..0ff843a4271 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java @@ -28,7 +28,6 @@ package jdk.nashorn.internal.runtime; import java.text.MessageFormat; import java.util.Locale; import java.util.ResourceBundle; - import jdk.nashorn.api.scripting.NashornException; import jdk.nashorn.internal.scripts.JS; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java index 087b34554bc..7e01fd6e2ea 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java @@ -36,6 +36,18 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; */ public interface GlobalObject { + /** + * Is this global of the given Context? + * @return true if this global belongs to the given Context + */ + public boolean isOfContext(Context context); + + /** + * Does this global belong to a strict Context? + * @return true if this global belongs to a strict Context + */ + public boolean isStrictContext(); + /** * Initialize standard builtin objects like "Object", "Array", "Function" etc. * as well as our extension builtin objects like "Java", "JSAdapter" as properties diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java new file mode 100644 index 00000000000..3c430b29e03 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSObjectListAdapter.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime; + +import jdk.nashorn.api.scripting.JSObject; + +/** + * A ListAdapter that can wraps a JSObject. + */ +public final class JSObjectListAdapter extends ListAdapter { + /** + * Creates a new list wrapper for the specified JSObject. + * @param obj JSOcript the object to wrap + */ + public JSObjectListAdapter(final JSObject obj) { + super(obj); + } + + @Override + public int size() { + return JSType.toInt32(((JSObject)obj).getMember("length")); + } + + @Override + protected Object getAt(int index) { + return ((JSObject)obj).getSlot(index); + } + + @Override + protected void setAt(int index, Object element) { + ((JSObject)obj).setSlot(index, element); + } +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java index 073c237c69b..93f0835b465 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java @@ -28,11 +28,14 @@ package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; +import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.util.Locale; +import java.lang.reflect.Array; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.parser.Lexer; +import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator; import jdk.nashorn.internal.runtime.linker.Bootstrap; /** @@ -40,25 +43,28 @@ import jdk.nashorn.internal.runtime.linker.Bootstrap; */ public enum JSType { /** The undefined type */ - UNDEFINED, + UNDEFINED("undefined"), /** The null type */ - NULL, + NULL("object"), /** The boolean type */ - BOOLEAN, + BOOLEAN("boolean"), /** The number type */ - NUMBER, + NUMBER("number"), /** The string type */ - STRING, + STRING("string"), /** The object type */ - OBJECT, + OBJECT("object"), /** The function type */ - FUNCTION; + FUNCTION("function"); + + /** The type name as returned by ECMAScript "typeof" operator*/ + private final String typeName; /** Max value for an uint32 in JavaScript */ public static final long MAX_UINT = 0xFFFF_FFFFL; @@ -109,14 +115,22 @@ public enum JSType { private static final double INT32_LIMIT = 4294967296.0; + /** + * Constructor + * + * @param typeName the type name + */ + private JSType(final String typeName) { + this.typeName = typeName; + } + /** * The external type name as returned by ECMAScript "typeof" operator * * @return type name for this type */ public final String typeName() { - // For NULL, "object" has to be returned! - return ((this == NULL) ? OBJECT : this).name().toLowerCase(Locale.ENGLISH); + return this.typeName; } /** @@ -127,31 +141,32 @@ public enum JSType { * @return the JSType for the object */ public static JSType of(final Object obj) { - if (obj == ScriptRuntime.UNDEFINED) { - return JSType.UNDEFINED; - } - + // Order of these statements is tuned for performance (see JDK-8024476) if (obj == null) { return JSType.NULL; } + if (obj instanceof ScriptObject) { + return (obj instanceof ScriptFunction) ? JSType.FUNCTION : JSType.OBJECT; + } + if (obj instanceof Boolean) { return JSType.BOOLEAN; } - if (obj instanceof Number) { - return JSType.NUMBER; - } - if (obj instanceof String || obj instanceof ConsString) { return JSType.STRING; } - if (Bootstrap.isCallable(obj)) { - return JSType.FUNCTION; + if (obj instanceof Number) { + return JSType.NUMBER; } - return JSType.OBJECT; + if (obj == ScriptRuntime.UNDEFINED) { + return JSType.UNDEFINED; + } + + return Bootstrap.isCallable(obj) ? JSType.FUNCTION : JSType.OBJECT; } /** @@ -848,6 +863,53 @@ public enum JSType { return ((GlobalObject)global).wrapAsObject(obj); } + /** + * Script object to Java array conversion. + * + * @param obj script object to be converted to Java array + * @param componentType component type of the destination array required + * @return converted Java array + */ + public static Object toJavaArray(final Object obj, final Class componentType) { + if (obj instanceof ScriptObject) { + return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType); + } else if (obj instanceof JSObject) { + final ArrayLikeIterator itr = ArrayLikeIterator.arrayLikeIterator(obj); + final int len = (int) itr.getLength(); + final Object[] res = new Object[len]; + int idx = 0; + while (itr.hasNext()) { + res[idx++] = itr.next(); + } + return convertArray(res, componentType); + } else { + throw new IllegalArgumentException("not a script object"); + } + } + + /** + * Java array to java array conversion - but using type conversions implemented by linker. + * + * @param src source array + * @param componentType component type of the destination array required + * @return converted Java array + */ + public static Object convertArray(final Object[] src, final Class componentType) { + final int l = src.length; + final Object dst = Array.newInstance(componentType, l); + final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType); + try { + for (int i = 0; i < src.length; i++) { + Array.set(dst, i, invoke(converter, src[i])); + } + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } + return dst; + } + /** * Check if an object is null or undefined * @@ -953,4 +1015,13 @@ public enum JSType { return Double.NaN; } + private static Object invoke(final MethodHandle mh, final Object arg) { + try { + return mh.invoke(arg); + } catch (final RuntimeException | Error e) { + throw e; + } catch (final Throwable t) { + throw new RuntimeException(t); + } + } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java index ae6d74461a1..41d34600de4 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java @@ -32,6 +32,7 @@ import java.util.ListIterator; import java.util.NoSuchElementException; import java.util.RandomAccess; import java.util.concurrent.Callable; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.InvokeByName; @@ -48,7 +49,7 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; * operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and * {@code pop}. */ -public final class ListAdapter extends AbstractList implements RandomAccess, Deque { +public abstract class ListAdapter extends AbstractList implements RandomAccess, Deque { // These add to the back and front of the list private static final Object PUSH = new Object(); private static InvokeByName getPUSH() { @@ -56,7 +57,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("push", ScriptObject.class, void.class, Object.class); + return new InvokeByName("push", Object.class, void.class, Object.class); } }); } @@ -67,7 +68,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("unshift", ScriptObject.class, void.class, Object.class); + return new InvokeByName("unshift", Object.class, void.class, Object.class); } }); } @@ -79,7 +80,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("pop", ScriptObject.class, Object.class); + return new InvokeByName("pop", Object.class, Object.class); } }); } @@ -90,7 +91,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("shift", ScriptObject.class, Object.class); + return new InvokeByName("shift", Object.class, Object.class); } }); } @@ -102,7 +103,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class, Object.class); + return new InvokeByName("splice", Object.class, void.class, int.class, int.class, Object.class); } }); } @@ -113,40 +114,52 @@ public final class ListAdapter extends AbstractList implements RandomAcc new Callable() { @Override public InvokeByName call() { - return new InvokeByName("splice", ScriptObject.class, void.class, int.class, int.class); + return new InvokeByName("splice", Object.class, void.class, int.class, int.class); } }); } - private final ScriptObject obj; + protected final Object obj; - /** - * Creates a new list wrapper for the specified script object. - * @param obj script the object to wrap - */ - public ListAdapter(ScriptObject obj) { + // allow subclasses only in this package + ListAdapter(Object obj) { this.obj = obj; } - @Override - public int size() { - return JSType.toInt32(obj.getLength()); + /** + * Factory to create a ListAdapter for a given script object. + * + * @param obj script object to wrap as a ListAdapter + * @return A ListAdapter wrapper object + */ + public static ListAdapter create(final Object obj) { + if (obj instanceof ScriptObject) { + return new ScriptObjectListAdapter((ScriptObject)obj); + } else if (obj instanceof JSObject) { + return new JSObjectListAdapter((JSObject)obj); + } else { + throw new IllegalArgumentException("ScriptObject or JSObject expected"); + } } @Override - public Object get(int index) { + public final Object get(int index) { checkRange(index); - return obj.get(index); + return getAt(index); } + protected abstract Object getAt(final int index); + @Override public Object set(int index, Object element) { checkRange(index); - final Object prevValue = get(index); - obj.set(index, element, false); + final Object prevValue = getAt(index); + setAt(index, element); return prevValue; } + protected abstract void setAt(int index, Object element); + private void checkRange(int index) { if(index < 0 || index >= size()) { throw invalidIndex(index); @@ -154,18 +167,18 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void push(Object e) { + public final void push(Object e) { addFirst(e); } @Override - public boolean add(Object e) { + public final boolean add(Object e) { addLast(e); return true; } @Override - public void addFirst(Object e) { + public final void addFirst(Object e) { try { final InvokeByName unshiftInvoker = getUNSHIFT(); final Object fn = unshiftInvoker.getGetter().invokeExact(obj); @@ -179,7 +192,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void addLast(Object e) { + public final void addLast(Object e) { try { final InvokeByName pushInvoker = getPUSH(); final Object fn = pushInvoker.getGetter().invokeExact(obj); @@ -193,7 +206,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public void add(int index, Object e) { + public final void add(int index, Object e) { try { if(index < 0) { throw invalidIndex(index); @@ -229,40 +242,40 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public boolean offer(Object e) { + public final boolean offer(Object e) { return offerLast(e); } @Override - public boolean offerFirst(Object e) { + public final boolean offerFirst(Object e) { addFirst(e); return true; } @Override - public boolean offerLast(Object e) { + public final boolean offerLast(Object e) { addLast(e); return true; } @Override - public Object pop() { + public final Object pop() { return removeFirst(); } @Override - public Object remove() { + public final Object remove() { return removeFirst(); } @Override - public Object removeFirst() { + public final Object removeFirst() { checkNonEmpty(); return invokeShift(); } @Override - public Object removeLast() { + public final Object removeLast() { checkNonEmpty(); return invokePop(); } @@ -274,7 +287,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public Object remove(int index) { + public final Object remove(int index) { if(index < 0) { throw invalidIndex(index); } else if (index == 0) { @@ -320,7 +333,7 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - protected void removeRange(int fromIndex, int toIndex) { + protected final void removeRange(int fromIndex, int toIndex) { invokeSpliceRemove(fromIndex, toIndex - fromIndex); } @@ -338,54 +351,54 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public Object poll() { + public final Object poll() { return pollFirst(); } @Override - public Object pollFirst() { + public final Object pollFirst() { return isEmpty() ? null : invokeShift(); } @Override - public Object pollLast() { + public final Object pollLast() { return isEmpty() ? null : invokePop(); } @Override - public Object peek() { + public final Object peek() { return peekFirst(); } @Override - public Object peekFirst() { + public final Object peekFirst() { return isEmpty() ? null : get(0); } @Override - public Object peekLast() { + public final Object peekLast() { return isEmpty() ? null : get(size() - 1); } @Override - public Object element() { + public final Object element() { return getFirst(); } @Override - public Object getFirst() { + public final Object getFirst() { checkNonEmpty(); return get(0); } @Override - public Object getLast() { + public final Object getLast() { checkNonEmpty(); return get(size() - 1); } @Override - public Iterator descendingIterator() { + public final Iterator descendingIterator() { final ListIterator it = listIterator(size()); return new Iterator() { @Override @@ -406,12 +419,12 @@ public final class ListAdapter extends AbstractList implements RandomAcc } @Override - public boolean removeFirstOccurrence(Object o) { + public final boolean removeFirstOccurrence(Object o) { return removeOccurrence(o, iterator()); } @Override - public boolean removeLastOccurrence(Object o) { + public final boolean removeLastOccurrence(Object o) { return removeOccurrence(o, descendingIterator()); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java index 4e349730451..e7837013f53 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/NashornLoader.java @@ -38,10 +38,7 @@ import java.security.SecureClassLoader; import jdk.nashorn.tools.Shell; /** - * Superclass for Nashorn class loader classes. This stores Context - * instance as an instance field. The current context can be - * efficiently accessed from a given Class via it's ClassLoader. - * + * Superclass for Nashorn class loader classes. */ abstract class NashornLoader extends SecureClassLoader { private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects"; @@ -69,27 +66,8 @@ abstract class NashornLoader extends SecureClassLoader { }; } - private final Context context; - - final Context getContext() { - return context; - } - - NashornLoader(final ClassLoader parent, final Context context) { + NashornLoader(final ClassLoader parent) { super(parent); - this.context = context; - } - - - /** - * Called by subclass after package access check is done - * @param name name of the class to be loaded - * @param resolve whether the class should be resolved or not - * @return Class object - * @throws ClassNotFoundException if class cannot be loaded - */ - protected final Class loadClassTrusted(final String name, final boolean resolve) throws ClassNotFoundException { - return super.loadClass(name, resolve); } protected static void checkPackageAccess(final String name) { @@ -122,10 +100,6 @@ abstract class NashornLoader extends SecureClassLoader { return permCollection; } - static boolean isStructureClass(final String fullName) { - return fullName.startsWith(SCRIPTS_PKG); - } - /** * Create a secure URL class loader for the given classpath * @param classPath classpath for the loader to search from diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java index 9e725e339df..99ba9e19fa5 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java @@ -198,7 +198,7 @@ public final class NativeJavaPackage extends ScriptObject { final String propertyName = desc.getNameToken(2); final String fullName = name.isEmpty() ? propertyName : name + "." + propertyName; - final Context context = getContext(); + final Context context = Context.getContextTrusted(); Class javaClass = null; try { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java index 370faf312d0..736932ea318 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptLoader.java @@ -33,17 +33,42 @@ import java.security.ProtectionDomain; * */ final class ScriptLoader extends NashornLoader { + private static final String NASHORN_PKG_PREFIX = "jdk.nashorn.internal."; + + private final Context context; + + /*package-private*/ Context getContext() { + return context; + } + /** * Constructor. */ - ScriptLoader(final StructureLoader parent, final Context context) { - super(parent, context); + ScriptLoader(final ClassLoader parent, final Context context) { + super(parent); + this.context = context; } @Override protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { checkPackageAccess(name); - return super.loadClassTrusted(name, resolve); + try { + return super.loadClass(name, resolve); + } catch (final ClassNotFoundException | SecurityException e) { + // We'll get ClassNotFoundException for Nashorn 'struct' classes. + // Also, we'll get SecurityException for jdk.nashorn.internal.* + // classes. So, load these using to context's 'shared' loader. + // All these classes start with "jdk.nashorn.internal." prefix. + try { + if (name.startsWith(NASHORN_PKG_PREFIX)) { + return context.getSharedLoader().loadClass(name); + } + } catch (final ClassNotFoundException ignored) { + } + + // throw the original exception from here + throw e; + } } // package-private and private stuff below this point diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index 9d7a7a6b260..a4ca6017b79 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -87,6 +87,8 @@ import jdk.nashorn.internal.runtime.linker.NashornGuards; */ public abstract class ScriptObject extends PropertyListenerManager implements PropertyAccess { + /** __proto__ special property name */ + public static final String PROTO_PROPERTY_NAME = "__proto__"; /** Search fall back routine name for "no such method" */ static final String NO_SUCH_METHOD_NAME = "__noSuchMethod__"; @@ -118,9 +120,6 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** objects proto. */ private ScriptObject proto; - /** Context of the object, lazily cached. */ - private Context context; - /** Object flags. */ private int flags; @@ -130,6 +129,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** Indexed array data. */ private ArrayData arrayData; + static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class); + static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class); + static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class); static final MethodHandle SETSPILL = findOwnMH("setSpill", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); static final MethodHandle SETSPILLWITHNEW = findOwnMH("setSpillWithNew", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, int.class, Object.class, Object.class); @@ -150,6 +152,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** Method handle for setting the proto of a ScriptObject */ public static final Call SET_PROTO = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class); + /** Method handle for setting the proto of a ScriptObject after checking argument */ + public static final Call SET_PROTO_CHECK = virtualCallNoLookup(ScriptObject.class, "setProtoCheck", void.class, Object.class); + /** Method handle for setting the user accessors of a ScriptObject */ public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class); @@ -1034,41 +1039,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr set(key, value, false); } - /** - * Return true if the script object context is strict - * @return true if strict context - */ - public final boolean isStrictContext() { - return getContext()._strict; - } - - /** - * Checks if this object belongs to the given context - * @param ctx context to check against - * @return true if this object belongs to the given context - */ - public final boolean isOfContext(final Context ctx) { - return context == ctx; - } - /** * Return the current context from the object's map. * @return Current context. */ - protected final Context getContext() { - if (context == null) { - context = Context.fromClass(getClass()); - } - return context; - } - - /** - * Set the current context. - * @param ctx context instance to set - */ - protected final void setContext(final Context ctx) { - ctx.getClass(); - this.context = ctx; + protected Context getContext() { + return Context.fromClass(getClass()); } /** @@ -1474,9 +1450,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr /** * Clears the properties from a ScriptObject * (java.util.Map-like method to help ScriptObjectMirror implementation) + * + * @param strict strict mode or not */ - public void clear() { - final boolean strict = isStrictContext(); + public void clear(final boolean strict) { final Iterator iter = propertyIterator(); while (iter.hasNext()) { delete(iter.next(), strict); @@ -1560,11 +1537,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * * @param key property key * @param value property value + * @param strict strict mode or not * @return oldValue if property with same key existed already */ - public Object put(final Object key, final Object value) { + public Object put(final Object key, final Object value, final boolean strict) { final Object oldValue = get(key); - set(key, value, isStrictContext()); + set(key, value, strict); return oldValue; } @@ -1574,9 +1552,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * (java.util.Map-like method to help ScriptObjectMirror implementation) * * @param otherMap a {@literal } map of properties to add + * @param strict strict mode or not */ - public void putAll(final Map otherMap) { - final boolean strict = isStrictContext(); + public void putAll(final Map otherMap, final boolean strict) { for (final Map.Entry entry : otherMap.entrySet()) { set(entry.getKey(), entry.getValue(), strict); } @@ -1587,25 +1565,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * (java.util.Map-like method to help ScriptObjectMirror implementation) * * @param key the key of the property + * @param strict strict mode or not * @return the oldValue of the removed property */ - public Object remove(final Object key) { + public Object remove(final Object key, final boolean strict) { final Object oldValue = get(key); - delete(key, isStrictContext()); + delete(key, strict); return oldValue; } - /** - * Delete a property from the ScriptObject. - * (to help ScriptObjectMirror implementation) - * - * @param key the key of the property - * @return if the delete was successful or not - */ - public boolean delete(final Object key) { - return delete(key, isStrictContext()); - } - /** * Return the size of the ScriptObject - i.e. the number of properties * it contains @@ -1745,6 +1713,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr MethodHandle methodHandle; if (find == null) { + if (PROTO_PROPERTY_NAME.equals(name)) { + return new GuardedInvocation(GETPROTO, NashornGuards.getScriptObjectGuard()); + } + if ("getProp".equals(operator)) { return noSuchProperty(desc, request); } else if ("getMethod".equals(operator)) { @@ -1851,6 +1823,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * toString = function() { print("global toString"); } // don't affect Object.prototype.toString */ FindProperty find = findProperty(name, true, scope, this); + // If it's not a scope search, then we don't want any inherited properties except those with user defined accessors. if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { // We should still check if inherited data property is not writable @@ -1866,9 +1839,12 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr // Existing, non-writable property return createEmptySetMethod(desc, "property.not.writable", true); } - } else if (!isExtensible()) { - // Non-existing property on a non-extensible object - return createEmptySetMethod(desc, "object.non.extensible", false); + } else { + if (PROTO_PROPERTY_NAME.equals(name)) { + return new GuardedInvocation(SETPROTOCHECK, NashornGuards.getScriptObjectGuard()); + } else if (! isExtensible()) { + return createEmptySetMethod(desc, "object.non.extensible", false); + } } return new SetMethodCreator(this, find, desc).createGuardedInvocation(); @@ -2317,11 +2293,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return; } - final boolean isStrict = isStrictContext(); - if (newLength > arrayLength) { setArray(getArray().ensure(newLength - 1)); - if (getArray().canDelete(arrayLength, (newLength - 1), isStrict)) { + if (getArray().canDelete(arrayLength, (newLength - 1), false)) { setArray(getArray().delete(arrayLength, (newLength - 1))); } return; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java new file mode 100644 index 00000000000..4fe2dc408f0 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObjectListAdapter.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime; + +/** + * A ListAdapter that can wrap a ScriptObject. + */ +public final class ScriptObjectListAdapter extends ListAdapter { + /** + * Creates a new list wrapper for the specified ScriptObject. + * @param obj script the object to wrap + */ + public ScriptObjectListAdapter(final ScriptObject obj) { + super(obj); + } + + @Override + public int size() { + return JSType.toInt32(((ScriptObject)obj).getLength()); + } + + @Override + protected Object getAt(int index) { + return ((ScriptObject)obj).get(index); + } + + @Override + protected void setAt(int index, Object element) { + ((ScriptObject)obj).set(index, element, false); + } +} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index 0fa0cc8a94e..c9b40512009 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -43,6 +43,7 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Objects; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.ir.debug.JSONWriter; @@ -190,8 +191,8 @@ public final class ScriptRuntime { case FUNCTION: if (self instanceof ScriptObject) { className = ((ScriptObject)self).getClassName(); - } else if (self instanceof ScriptObjectMirror) { - className = ((ScriptObjectMirror)self).getClassName(); + } else if (self instanceof JSObject) { + className = ((JSObject)self).getClassName(); } else { className = self.getClass().getName(); } @@ -245,8 +246,8 @@ public final class ScriptRuntime { return new RangeIterator(Array.getLength(obj)); } - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)obj).keySet().iterator(); + if (obj instanceof JSObject) { + return ((JSObject)obj).keySet().iterator(); } if (obj instanceof List) { @@ -323,8 +324,8 @@ public final class ScriptRuntime { }; } - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)obj).values().iterator(); + if (obj instanceof JSObject) { + return ((JSObject)obj).values().iterator(); } if (obj instanceof Map) { @@ -351,35 +352,6 @@ public final class ScriptRuntime { return global; } - /** - * Check that the target function is associated with current Context. And also make sure that 'self', if - * ScriptObject, is from current context. - * - * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve - * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker} - * for operation {@code "dyn:call"}, then using its {@link MethodHandle#invokeExact(Object...)} method instead. - * - * @param target ScriptFunction object. - * @param self Receiver in call. - * @param args Call arguments. - * @return Call result. - */ - public static Object checkAndApply(final ScriptFunction target, final Object self, final Object... args) { - final ScriptObject global = Context.getGlobalTrusted(); - assert (global instanceof GlobalObject): "No current global set"; - - if (target.getContext() != global.getContext()) { - throw new IllegalArgumentException("'target' function is not from current Context"); - } - - if (self instanceof ScriptObject && ((ScriptObject)self).getContext() != global.getContext()) { - throw new IllegalArgumentException("'self' object is not from current Context"); - } - - // all in order - call real 'apply' - return apply(target, self, args); - } - /** * Call a function given self and args. If the number of the arguments is known in advance, you can likely achieve * better performance by {@link Bootstrap#createDynamicInvoker(String, Class, Class...) creating a dynamic invoker} @@ -400,28 +372,6 @@ public final class ScriptRuntime { } } - /** - * Check that the target function is associated with current Context. - * And also make sure that 'self', if ScriptObject, is from current context. - * - * Call a function as a constructor given args. - * - * @param target ScriptFunction object. - * @param args Call arguments. - * @return Constructor call result. - */ - public static Object checkAndConstruct(final ScriptFunction target, final Object... args) { - final ScriptObject global = Context.getGlobalTrusted(); - assert (global instanceof GlobalObject): "No current global set"; - - if (target.getContext() != global.getContext()) { - throw new IllegalArgumentException("'target' function is not from current Context"); - } - - // all in order - call real 'construct' - return construct(target, args); - } - /** * Call a script function as a constructor with given args. * @@ -520,9 +470,12 @@ public final class ScriptRuntime { throw typeError(global, "cant.apply.with.to.null"); } - final ScriptObject withObject = new WithObject(scope, JSType.toScriptObject(global, expression)); + final Object wrappedExpr = JSType.toScriptObject(global, expression); + if (wrappedExpr instanceof ScriptObject) { + return new WithObject(scope, (ScriptObject)wrappedExpr); + } - return withObject; + throw typeError(global, "cant.apply.with.to.non.scriptobject"); } /** @@ -534,7 +487,7 @@ public final class ScriptRuntime { */ public static ScriptObject closeWith(final ScriptObject scope) { if (scope instanceof WithObject) { - return scope.getProto(); + return ((WithObject)scope).getParentScope(); } return scope; } @@ -619,8 +572,8 @@ public final class ScriptRuntime { throw typeError("cant.get.property", safeToString(property), "null"); } else if (JSType.isPrimitive(obj)) { obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property); - } else if (obj instanceof ScriptObjectMirror) { - obj = ((ScriptObjectMirror)obj).getMember(property.toString()); + } else if (obj instanceof JSObject) { + obj = ((JSObject)obj).getMember(property.toString()); } else { obj = UNDEFINED; } @@ -672,6 +625,11 @@ public final class ScriptRuntime { return ((ScriptObject) JSType.toScriptObject(obj)).delete(property, Boolean.TRUE.equals(strict)); } + if (obj instanceof JSObject) { + ((JSObject)obj).removeMember(Objects.toString(property)); + return true; + } + // if object is not reference type, vacuously delete is successful. return true; } @@ -863,6 +821,10 @@ public final class ScriptRuntime { return ((ScriptObject)obj).has(property); } + if (obj instanceof JSObject) { + return ((JSObject)obj).hasMember(Objects.toString(property)); + } + return false; } @@ -889,11 +851,13 @@ public final class ScriptRuntime { return ((StaticClass)clazz).getRepresentedClass().isInstance(obj); } - if (clazz instanceof ScriptObjectMirror) { - if (obj instanceof ScriptObjectMirror) { - return ((ScriptObjectMirror)clazz).isInstance((ScriptObjectMirror)obj); - } - return false; + if (clazz instanceof JSObject) { + return ((JSObject)clazz).isInstance(obj); + } + + // provide for reverse hook + if (obj instanceof JSObject) { + return ((JSObject)obj).isInstanceOf(clazz); } throw typeError("instanceof.on.non.object"); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java index bdc40eddcc9..41201cde847 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java @@ -34,7 +34,6 @@ import jdk.nashorn.internal.codegen.ObjectClassGenerator; /** * Responsible for on the fly construction of structure classes. - * */ final class StructureLoader extends NashornLoader { private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName(); @@ -42,27 +41,17 @@ final class StructureLoader extends NashornLoader { /** * Constructor. */ - StructureLoader(final ClassLoader parent, final Context context) { - super(parent, context); + StructureLoader(final ClassLoader parent) { + super(parent); } - @Override - protected synchronized Class loadClass(final String name, final boolean resolve) throws ClassNotFoundException { - // check the cache first - final Class loadedClass = findLoadedClass(name); - if (loadedClass != null) { - if (resolve) { - resolveClass(loadedClass); - } - return loadedClass; - } - - return super.loadClassTrusted(name, resolve); + static boolean isStructureClass(final String name) { + return name.startsWith(JS_OBJECT_PREFIX_EXTERNAL); } @Override protected Class findClass(final String name) throws ClassNotFoundException { - if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) { + if (isStructureClass(name)) { return generateClass(name, name.substring(JS_OBJECT_PREFIX_EXTERNAL.length())); } return super.findClass(name); @@ -75,11 +64,7 @@ final class StructureLoader extends NashornLoader { * @return Generated class. */ private Class generateClass(final String name, final String descriptor) { - Context context = getContext(); - - if (context == null) { - context = Context.getContextTrusted(); - } + final Context context = Context.getContextTrusted(); final byte[] code = new ObjectClassGenerator(context).generate(descriptor); return defineClass(name, code, 0, code.length, new ProtectionDomain(null, getPermissions(null))); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java index 46de1d13ee5..7dc8307cd91 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/WithObject.java @@ -30,26 +30,26 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.invoke.SwitchPoint; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; - /** * This class supports the handling of scope in a with body. * */ public final class WithObject extends ScriptObject implements Scope { - + private static final MethodHandle WITHEXPRESSIONGUARD = findOwnMH("withExpressionGuard", boolean.class, Object.class, PropertyMap.class, SwitchPoint.class); private static final MethodHandle WITHEXPRESSIONFILTER = findOwnMH("withFilterExpression", Object.class, Object.class); private static final MethodHandle WITHSCOPEFILTER = findOwnMH("withFilterScope", Object.class, Object.class); private static final MethodHandle BIND_TO_EXPRESSION_OBJ = findOwnMH("bindToExpression", Object.class, Object.class, Object.class); private static final MethodHandle BIND_TO_EXPRESSION_FN = findOwnMH("bindToExpression", Object.class, ScriptFunction.class, Object.class); /** With expression object. */ - private final Object expression; + private final ScriptObject expression; /** * Constructor @@ -57,12 +57,13 @@ public final class WithObject extends ScriptObject implements Scope { * @param scope scope object * @param expression with expression */ - WithObject(final ScriptObject scope, final Object expression) { + WithObject(final ScriptObject scope, final ScriptObject expression) { super(scope, null); setIsScope(); this.expression = expression; } + /** * Delete a property based on a key. * @param key Any valid JavaScript value. @@ -71,15 +72,13 @@ public final class WithObject extends ScriptObject implements Scope { */ @Override public boolean delete(final Object key, final boolean strict) { - if (expression instanceof ScriptObject) { - final ScriptObject self = (ScriptObject)expression; - final String propName = JSType.toString(key); + final ScriptObject self = expression; + final String propName = JSType.toString(key); - final FindProperty find = self.findProperty(propName, true); + final FindProperty find = self.findProperty(propName, true); - if (find != null) { - return self.delete(propName, strict); - } + if (find != null) { + return self.delete(propName, strict); } return false; @@ -105,18 +104,16 @@ public final class WithObject extends ScriptObject implements Scope { name = null; } - if (expression instanceof ScriptObject) { - self = (ScriptObject)expression; - if (isNamedOperation) { - find = self.findProperty(name, true); - } + self = expression; + if (isNamedOperation) { + find = self.findProperty(name, true); + } - if (find != null) { - link = self.lookup(desc, request); + if (find != null) { + link = self.lookup(desc, request); - if (link != null) { - return fixExpressionCallSite(ndesc, link); - } + if (link != null) { + return fixExpressionCallSite(ndesc, link); } } @@ -126,7 +123,7 @@ public final class WithObject extends ScriptObject implements Scope { } if (find != null) { - return fixScopeCallSite(scope.lookup(desc, request)); + return fixScopeCallSite(scope.lookup(desc, request), name); } // the property is not found - now check for @@ -178,7 +175,7 @@ public final class WithObject extends ScriptObject implements Scope { link = scope.lookup(desc, request); if (link != null) { - return fixScopeCallSite(link); + return fixScopeCallSite(link, name); } return null; @@ -197,11 +194,9 @@ public final class WithObject extends ScriptObject implements Scope { */ @Override FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) { - if (expression instanceof ScriptObject) { - final FindProperty exprProperty = ((ScriptObject)expression).findProperty(key, deep, stopOnNonScope, start); - if(exprProperty != null) { - return exprProperty; - } + final FindProperty exprProperty = expression.findProperty(key, deep, stopOnNonScope, start); + if (exprProperty != null) { + return exprProperty; } return super.findProperty(key, deep, stopOnNonScope, start); } @@ -220,16 +215,17 @@ public final class WithObject extends ScriptObject implements Scope { * Get first parent scope that is not an instance of WithObject. */ private Scope getNonWithParent() { - ScriptObject proto = getProto(); + ScriptObject proto = getParentScope(); while (proto != null && proto instanceof WithObject) { - proto = proto.getProto(); + proto = ((WithObject)proto).getParentScope(); } assert proto instanceof Scope : "with scope without parent scope"; return (Scope) proto; } + private static GuardedInvocation fixReceiverType(final GuardedInvocation link, final MethodHandle filter) { // The receiver may be an Object or a ScriptObject. final MethodType invType = link.getInvocation().type(); @@ -256,9 +252,13 @@ public final class WithObject extends ScriptObject implements Scope { filterGuard(link, WITHEXPRESSIONFILTER)); } - private static GuardedInvocation fixScopeCallSite(final GuardedInvocation link) { + private GuardedInvocation fixScopeCallSite(final GuardedInvocation link, final String name) { final GuardedInvocation newLink = fixReceiverType(link, WITHSCOPEFILTER); - return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER), filterGuard(newLink, WITHSCOPEFILTER)); + return link.replaceMethods(filter(newLink.getInvocation(), WITHSCOPEFILTER), + MH.guardWithTest( + expressionGuard(name), + filterGuard(newLink, WITHSCOPEFILTER), + MH.dropArguments(MH.constant(boolean.class, false), 0, Object.class))); } private static MethodHandle filterGuard(final GuardedInvocation link, final MethodHandle filter) { @@ -279,7 +279,6 @@ public final class WithObject extends ScriptObject implements Scope { return ((WithObject)receiver).expression; } - @SuppressWarnings("unused") private static Object bindToExpression(final Object fn, final Object receiver) { return fn instanceof ScriptFunction ? bindToExpression((ScriptFunction) fn, receiver) : fn; @@ -289,6 +288,17 @@ public final class WithObject extends ScriptObject implements Scope { return fn.makeBoundFunction(withFilterExpression(receiver), new Object[0]); } + private MethodHandle expressionGuard(final String name) { + final PropertyMap map = expression.getMap(); + final SwitchPoint sp = map.getProtoGetSwitchPoint(expression.getProto(), name); + return MH.insertArguments(WITHEXPRESSIONGUARD, 1, map, sp); + } + + @SuppressWarnings("unused") + private static boolean withExpressionGuard(final Object receiver, final PropertyMap map, final SwitchPoint sp) { + return ((WithObject)receiver).expression.getMap() == map && (sp == null || !sp.hasBeenInvalidated()); + } + /** * Drops the WithObject wrapper from the scope. * @param receiver WithObject wrapper. @@ -302,10 +312,14 @@ public final class WithObject extends ScriptObject implements Scope { * Get the with expression for this {@code WithObject} * @return the with expression */ - public Object getExpression() { + public ScriptObject getExpression() { return expression; } + public ScriptObject getParentScope() { + return getProto(); + } + private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { return MH.findStatic(MethodHandles.lookup(), WithObject.class, name, MH.type(rtype, types)); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java index 1278d49ff95..ca4adb62e97 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayData.java @@ -26,10 +26,9 @@ package jdk.nashorn.internal.runtime.arrays; import java.lang.invoke.MethodHandle; -import java.lang.reflect.Array; import jdk.nashorn.internal.runtime.GlobalObject; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.PropertyDescriptor; -import jdk.nashorn.internal.runtime.linker.Bootstrap; /** * ArrayData - abstraction for wrapping array elements @@ -204,20 +203,7 @@ public abstract class ArrayData { * @return and array of the given type */ public Object asArrayOfType(final Class componentType) { - final Object[] src = asObjectArray(); - final int l = src.length; - final Object dst = Array.newInstance(componentType, l); - final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType); - try { - for (int i = 0; i < src.length; i++) { - Array.set(dst, i, invoke(converter, src[i])); - } - } catch (final RuntimeException | Error e) { - throw e; - } catch (final Throwable t) { - throw new RuntimeException(t); - } - return dst; + return JSType.convertArray(asObjectArray(), componentType); } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java index 044b21d5879..962b1f9e031 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ArrayLikeIterator.java @@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays; import java.util.Iterator; import java.util.List; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.ScriptObject; @@ -127,8 +127,8 @@ abstract public class ArrayLikeIterator implements Iterator { return new ScriptObjectIterator((ScriptObject)obj, includeUndefined); } - if (obj instanceof ScriptObjectMirror) { - return new ScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); + if (obj instanceof JSObject) { + return new JSObjectIterator((JSObject)obj, includeUndefined); } if (obj instanceof List) { @@ -160,8 +160,8 @@ abstract public class ArrayLikeIterator implements Iterator { return new ReverseScriptObjectIterator((ScriptObject)obj, includeUndefined); } - if (obj instanceof ScriptObjectMirror) { - return new ReverseScriptObjectMirrorIterator((ScriptObjectMirror)obj, includeUndefined); + if (obj instanceof JSObject) { + return new ReverseJSObjectIterator((JSObject)obj, includeUndefined); } if (obj instanceof List) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java index 9b6cbb447fe..244739b389d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/IteratorAction.java @@ -27,7 +27,7 @@ package jdk.nashorn.internal.runtime.arrays; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptRuntime; @@ -101,9 +101,9 @@ public abstract class IteratorAction { final boolean strict; if (callbackfn instanceof ScriptFunction) { strict = ((ScriptFunction)callbackfn).isStrict(); - } else if (callbackfn instanceof ScriptObjectMirror && - ((ScriptObjectMirror)callbackfn).isFunction()) { - strict = ((ScriptObjectMirror)callbackfn).isStrictFunction(); + } else if (callbackfn instanceof JSObject && + ((JSObject)callbackfn).isFunction()) { + strict = ((JSObject)callbackfn).isStrictFunction(); } else if (Bootstrap.isDynamicMethod(callbackfn) || Bootstrap.isFunctionalInterfaceObject(callbackfn)) { strict = false; } else { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java similarity index 82% rename from nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java rename to nashorn/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java index a7bef158f57..885c77eb570 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ScriptObjectMirrorIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/JSObjectIterator.java @@ -26,21 +26,21 @@ package jdk.nashorn.internal.runtime.arrays; import java.util.NoSuchElementException; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.JSType; /** * Iterator over a ScriptObjectMirror */ -class ScriptObjectMirrorIterator extends ArrayLikeIterator { +class JSObjectIterator extends ArrayLikeIterator { - protected final ScriptObjectMirror obj; + protected final JSObject obj; private final long length; - ScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { + JSObjectIterator(final JSObject obj, final boolean includeUndefined) { super(includeUndefined); this.obj = obj; - this.length = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0); + this.length = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0); this.index = 0; } @@ -60,7 +60,7 @@ class ScriptObjectMirrorIterator extends ArrayLikeIterator { } while (indexInArray()) { - if (obj.containsKey(index) || includeUndefined) { + if (obj.hasSlot((int)index) || includeUndefined) { break; } bumpIndex(); @@ -72,7 +72,7 @@ class ScriptObjectMirrorIterator extends ArrayLikeIterator { @Override public Object next() { if (indexInArray()) { - return obj.get(bumpIndex()); + return obj.getSlot((int)bumpIndex()); } throw new NoSuchElementException(); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java similarity index 83% rename from nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java rename to nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java index 1e3e4000cdb..84c5c46dd12 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseScriptObjectMirrorIterator.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ReverseJSObjectIterator.java @@ -25,17 +25,17 @@ package jdk.nashorn.internal.runtime.arrays; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.runtime.JSType; /** * Reverse iterator over a ScriptObjectMirror */ -final class ReverseScriptObjectMirrorIterator extends ScriptObjectMirrorIterator { +final class ReverseJSObjectIterator extends JSObjectIterator { - ReverseScriptObjectMirrorIterator(final ScriptObjectMirror obj, final boolean includeUndefined) { + ReverseJSObjectIterator(final JSObject obj, final boolean includeUndefined) { super(obj, includeUndefined); - this.index = JSType.toUint32(obj.containsKey("length")? obj.getMember("length") : 0) - 1; + this.index = JSType.toUint32(obj.hasMember("length")? obj.getMember("length") : 0) - 1; } @Override diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java index e190224a07b..f725817af4b 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -39,7 +39,7 @@ import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkerServices; -import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.codegen.RuntimeCallSite; import jdk.nashorn.internal.runtime.JSType; @@ -87,7 +87,7 @@ public final class Bootstrap { } return obj instanceof ScriptFunction || - ((obj instanceof ScriptObjectMirror) && ((ScriptObjectMirror)obj).isFunction()) || + ((obj instanceof JSObject) && ((JSObject)obj).isFunction()) || isDynamicMethod(obj) || isFunctionalInterfaceObject(obj) || obj instanceof StaticClass; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java index 1b7eb66b4e9..45451a8bad7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java @@ -30,7 +30,6 @@ import jdk.nashorn.internal.lookup.MethodHandleFactory; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import java.util.Objects; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; @@ -88,8 +87,9 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { case "setElem": return c > 2 ? findSetMethod(desc) : findSetIndexMethod(); case "call": - case "callMethod": return findCallMethod(desc, operator); + case "callMethod": + return findCallMethodMethod(desc, operator); case "new": return findNewMethod(desc); default: @@ -98,33 +98,37 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { } private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) { - final MethodHandle getter = MH.insertArguments(JSOBJECT_GET, 1, desc.getNameToken(2)); + final MethodHandle getter = MH.insertArguments(JSOBJECT_GETMEMBER, 1, desc.getNameToken(2)); return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findGetIndexMethod() { - return new GuardedInvocation(JSOBJECT_GET, null, IS_JSOBJECT_GUARD); + return new GuardedInvocation(JSOBJECTLINKER_GET, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findSetMethod(final CallSiteDescriptor desc) { - final MethodHandle getter = MH.insertArguments(JSOBJECT_PUT, 1, desc.getNameToken(2)); + final MethodHandle getter = MH.insertArguments(JSOBJECT_SETMEMBER, 1, desc.getNameToken(2)); return new GuardedInvocation(getter, null, IS_JSOBJECT_GUARD); } private static GuardedInvocation findSetIndexMethod() { - return new GuardedInvocation(JSOBJECT_PUT, null, IS_JSOBJECT_GUARD); + return new GuardedInvocation(JSOBJECTLINKER_PUT, null, IS_JSOBJECT_GUARD); } - private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) { - // if operator is "call", then 'self' is a JSObject function object already. Use 'call' as the method name - final String methodName = "callMethod".equals(operator)? desc.getNameToken(2) : "call"; - MethodHandle func = MH.insertArguments(JSOBJECT_CALL, 1, methodName); + private static GuardedInvocation findCallMethodMethod(final CallSiteDescriptor desc, final String operator) { + final String methodName = desc.getNameToken(2); + MethodHandle func = MH.insertArguments(JSOBJECT_CALLMEMBER, 1, methodName); func = MH.asCollector(func, Object[].class, desc.getMethodType().parameterCount() - 1); return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); } + private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc, final String operator) { + final MethodHandle func = MH.asCollector(JSOBJECT_CALL, Object[].class, desc.getMethodType().parameterCount() - 2); + return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); + } + private static GuardedInvocation findNewMethod(final CallSiteDescriptor desc) { - MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1); + final MethodHandle func = MH.asCollector(JSOBJECT_NEW, Object[].class, desc.getMethodType().parameterCount() - 1); return new GuardedInvocation(func, null, IS_JSOBJECT_GUARD); } @@ -135,36 +139,30 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { @SuppressWarnings("unused") private static Object get(final Object jsobj, final Object key) { - if (key instanceof String) { - return ((JSObject)jsobj).getMember((String)key); + if (key instanceof Integer) { + return ((JSObject)jsobj).getSlot((int)(Integer)key); } else if (key instanceof Number) { final int index = getIndex((Number)key); if (index > -1) { return ((JSObject)jsobj).getSlot(index); } + } else if (key instanceof String) { + return ((JSObject)jsobj).getMember((String)key); } return null; } @SuppressWarnings("unused") private static void put(final Object jsobj, final Object key, final Object value) { - if (key instanceof String) { - ((JSObject)jsobj).setMember((String)key, value); + if (key instanceof Integer) { + ((JSObject)jsobj).setSlot((int)(Integer)key, value); } else if (key instanceof Number) { ((JSObject)jsobj).setSlot(getIndex((Number)key), value); + } else if (key instanceof String) { + ((JSObject)jsobj).setMember((String)key, value); } } - @SuppressWarnings("unused") - private static Object call(final Object jsobj, final Object method, final Object... args) { - return ((JSObject)jsobj).call(Objects.toString(method), args); - } - - @SuppressWarnings("unused") - private static Object newObject(final Object jsobj, final Object... args) { - return ((JSObject)jsobj).newObject(null, args); - } - private static int getIndex(final Number n) { final double value = n.doubleValue(); return JSType.isRepresentableAsInt(value) ? (int)value : -1; @@ -172,11 +170,17 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality(); - private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class); - private static final MethodHandle JSOBJECT_GET = findOwnMH("get", Object.class, Object.class, Object.class); - private static final MethodHandle JSOBJECT_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class); - private static final MethodHandle JSOBJECT_CALL = findOwnMH("call", Object.class, Object.class, Object.class, Object[].class); - private static final MethodHandle JSOBJECT_NEW = findOwnMH("newObject", Object.class, Object.class, Object[].class); + // method handles of the current class + private static final MethodHandle IS_JSOBJECT_GUARD = findOwnMH("isJSObject", boolean.class, Object.class); + private static final MethodHandle JSOBJECTLINKER_GET = findOwnMH("get", Object.class, Object.class, Object.class); + private static final MethodHandle JSOBJECTLINKER_PUT = findOwnMH("put", Void.TYPE, Object.class, Object.class, Object.class); + + // method handles of JSObject class + private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH("getMember", Object.class, String.class); + private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH("setMember", Void.TYPE, String.class, Object.class); + private static final MethodHandle JSOBJECT_CALLMEMBER = findJSObjectMH("callMember", Object.class, String.class, Object[].class); + private static final MethodHandle JSOBJECT_CALL = findJSObjectMH("call", Object.class, Object.class, Object[].class); + private static final MethodHandle JSOBJECT_NEW = findJSObjectMH("newObject", Object.class, Object[].class); private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) { final Class own = JSObjectLinker.class; @@ -187,4 +191,14 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { return MH.findVirtual(MethodHandles.lookup(), own, name, mt); } } + + private static MethodHandle findJSObjectMH(final String name, final Class rtype, final Class... types) { + final Class own = JSObject.class; + final MethodType mt = MH.type(rtype, types); + try { + return MH.findVirtual(MethodHandles.publicLookup(), own, name, mt); + } catch (final MethodHandleFactory.LookupException e) { + return MH.findVirtual(MethodHandles.lookup(), own, name, mt); + } + } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java index 68df99f3af3..f4edecc40ca 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java @@ -263,15 +263,6 @@ final class RegExpScanner extends Scanner { } if (atom()) { - // Check for character classes that never or always match - if (sb.toString().endsWith("[]")) { - sb.setLength(sb.length() - 1); - sb.append("^\\s\\S]"); - } else if (sb.toString().endsWith("[^]")) { - sb.setLength(sb.length() - 2); - sb.append("\\s\\S]"); - } - quantifier(); return true; } @@ -767,7 +758,18 @@ final class RegExpScanner extends Scanner { if (classRanges() && ch0 == ']') { pop(']'); - return commit(1); + commit(1); + + // Substitute empty character classes [] and [^] that never or always match + if (position == startIn + 2) { + sb.setLength(sb.length() - 1); + sb.append("^\\s\\S]"); + } else if (position == startIn + 3 && inNegativeClass) { + sb.setLength(sb.length() - 2); + sb.append("\\s\\S]"); + } + + return true; } } finally { inCharClass = false; // no nested character classes in JavaScript diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties index 68f68c0a25b..5115e2ce0c7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties @@ -110,6 +110,7 @@ type.error.cannot.get.default.string=Cannot get default string value type.error.cannot.get.default.number=Cannot get default number value type.error.cant.apply.with.to.null=Cannot apply "with" to null type.error.cant.apply.with.to.undefined=Cannot apply "with" to undefined +type.error.cant.apply.with.to.non.scriptobject=Cannot apply "with" to non script object type.error.in.with.non.object=Right hand side of "in" cannot be non-Object, found {0} type.error.prototype.not.an.object="prototype" of {0} is not an Object, it is {1} type.error.cant.load.script=Cannot load script from {0} diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js index 00559129298..b0bfc3fb1ee 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/base.js @@ -23,204 +23,126 @@ * questions. */ -Scene = Java.type("javafx.scene.Scene"); -Group = Java.type("javafx.scene.Group"); -Stage = Java.type("javafx.stage.Stage"); +var JFX_BASE_CLASSES = []; +var JFX_GRAPHICS_CLASSES = []; +var JFX_CONTROLS_CLASSES = []; +var JFX_FXML_CLASSES = []; +var JFX_WEB_CLASSES = []; +var JFX_MEDIA_CLASSES = []; +var JFX_SWING_CLASSES = []; +var JFX_SWT_CLASSES = []; -Binding = Java.type("javafx.beans.binding.Binding"); -Bindings = Java.type("javafx.beans.binding.Bindings"); -BooleanBinding = Java.type("javafx.beans.binding.BooleanBinding"); -BooleanExpression = Java.type("javafx.beans.binding.BooleanExpression"); -DoubleBinding = Java.type("javafx.beans.binding.DoubleBinding"); -DoubleExpression = Java.type("javafx.beans.binding.DoubleExpression"); -FloatBinding = Java.type("javafx.beans.binding.FloatBinding"); -FloatExpression = Java.type("javafx.beans.binding.FloatExpression"); -IntegerBinding = Java.type("javafx.beans.binding.IntegerBinding"); -IntegerExpression = Java.type("javafx.beans.binding.IntegerExpression"); -ListBinding = Java.type("javafx.beans.binding.ListBinding"); -ListExpression = Java.type("javafx.beans.binding.ListExpression"); -LongBinding = Java.type("javafx.beans.binding.LongBinding"); -LongExpression = Java.type("javafx.beans.binding.LongExpression"); -MapBinding = Java.type("javafx.beans.binding.MapBinding"); -MapExpression = Java.type("javafx.beans.binding.MapExpression"); -NumberBinding = Java.type("javafx.beans.binding.NumberBinding"); -NumberExpression = Java.type("javafx.beans.binding.NumberExpression"); -NumberExpressionBase = Java.type("javafx.beans.binding.NumberExpressionBase"); -ObjectBinding = Java.type("javafx.beans.binding.ObjectBinding"); -ObjectExpression = Java.type("javafx.beans.binding.ObjectExpression"); -SetBinding = Java.type("javafx.beans.binding.SetBinding"); -SetExpression = Java.type("javafx.beans.binding.SetExpression"); -StringBinding = Java.type("javafx.beans.binding.StringBinding"); -StringExpression = Java.type("javafx.beans.binding.StringExpression"); -When = Java.type("javafx.beans.binding.When"); -DefaultProperty = Java.type("javafx.beans.DefaultProperty"); -InvalidationListener = Java.type("javafx.beans.InvalidationListener"); -Observable = Java.type("javafx.beans.Observable"); -JavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.JavaBeanBooleanProperty"); -JavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanBooleanPropertyBuilder"); -JavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.JavaBeanDoubleProperty"); -JavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanDoublePropertyBuilder"); -JavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.JavaBeanFloatProperty"); -JavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanFloatPropertyBuilder"); -JavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.JavaBeanIntegerProperty"); -JavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanIntegerPropertyBuilder"); -JavaBeanLongProperty = Java.type("javafx.beans.property.adapter.JavaBeanLongProperty"); -JavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanLongPropertyBuilder"); -JavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.JavaBeanObjectProperty"); -JavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanObjectPropertyBuilder"); -JavaBeanProperty = Java.type("javafx.beans.property.adapter.JavaBeanProperty"); -JavaBeanStringProperty = Java.type("javafx.beans.property.adapter.JavaBeanStringProperty"); -JavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.JavaBeanStringPropertyBuilder"); -ReadOnlyJavaBeanBooleanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanProperty"); -ReadOnlyJavaBeanBooleanPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanBooleanPropertyBuilder"); -ReadOnlyJavaBeanDoubleProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoubleProperty"); -ReadOnlyJavaBeanDoublePropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanDoublePropertyBuilder"); -ReadOnlyJavaBeanFloatProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatProperty"); -ReadOnlyJavaBeanFloatPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanFloatPropertyBuilder"); -ReadOnlyJavaBeanIntegerProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerProperty"); -ReadOnlyJavaBeanIntegerPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanIntegerPropertyBuilder"); -ReadOnlyJavaBeanLongProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongProperty"); -ReadOnlyJavaBeanLongPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanLongPropertyBuilder"); -ReadOnlyJavaBeanObjectProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectProperty"); -ReadOnlyJavaBeanObjectPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanObjectPropertyBuilder"); -ReadOnlyJavaBeanProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanProperty"); -ReadOnlyJavaBeanStringProperty = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringProperty"); -ReadOnlyJavaBeanStringPropertyBuilder = Java.type("javafx.beans.property.adapter.ReadOnlyJavaBeanStringPropertyBuilder"); -BooleanProperty = Java.type("javafx.beans.property.BooleanProperty"); -BooleanPropertyBase = Java.type("javafx.beans.property.BooleanPropertyBase"); -DoubleProperty = Java.type("javafx.beans.property.DoubleProperty"); -DoublePropertyBase = Java.type("javafx.beans.property.DoublePropertyBase"); -FloatProperty = Java.type("javafx.beans.property.FloatProperty"); -FloatPropertyBase = Java.type("javafx.beans.property.FloatPropertyBase"); -IntegerProperty = Java.type("javafx.beans.property.IntegerProperty"); -IntegerPropertyBase = Java.type("javafx.beans.property.IntegerPropertyBase"); -ListProperty = Java.type("javafx.beans.property.ListProperty"); -ListPropertyBase = Java.type("javafx.beans.property.ListPropertyBase"); -LongProperty = Java.type("javafx.beans.property.LongProperty"); -LongPropertyBase = Java.type("javafx.beans.property.LongPropertyBase"); -MapProperty = Java.type("javafx.beans.property.MapProperty"); -MapPropertyBase = Java.type("javafx.beans.property.MapPropertyBase"); -ObjectProperty = Java.type("javafx.beans.property.ObjectProperty"); -ObjectPropertyBase = Java.type("javafx.beans.property.ObjectPropertyBase"); -Property = Java.type("javafx.beans.property.Property"); -ReadOnlyBooleanProperty = Java.type("javafx.beans.property.ReadOnlyBooleanProperty"); -ReadOnlyBooleanPropertyBase = Java.type("javafx.beans.property.ReadOnlyBooleanPropertyBase"); -ReadOnlyBooleanWrapper = Java.type("javafx.beans.property.ReadOnlyBooleanWrapper"); -ReadOnlyDoubleProperty = Java.type("javafx.beans.property.ReadOnlyDoubleProperty"); -ReadOnlyDoublePropertyBase = Java.type("javafx.beans.property.ReadOnlyDoublePropertyBase"); -ReadOnlyDoubleWrapper = Java.type("javafx.beans.property.ReadOnlyDoubleWrapper"); -ReadOnlyFloatProperty = Java.type("javafx.beans.property.ReadOnlyFloatProperty"); -ReadOnlyFloatPropertyBase = Java.type("javafx.beans.property.ReadOnlyFloatPropertyBase"); -ReadOnlyFloatWrapper = Java.type("javafx.beans.property.ReadOnlyFloatWrapper"); -ReadOnlyIntegerProperty = Java.type("javafx.beans.property.ReadOnlyIntegerProperty"); -ReadOnlyIntegerPropertyBase = Java.type("javafx.beans.property.ReadOnlyIntegerPropertyBase"); -ReadOnlyIntegerWrapper = Java.type("javafx.beans.property.ReadOnlyIntegerWrapper"); -ReadOnlyListProperty = Java.type("javafx.beans.property.ReadOnlyListProperty"); -ReadOnlyListPropertyBase = Java.type("javafx.beans.property.ReadOnlyListPropertyBase"); -ReadOnlyListWrapper = Java.type("javafx.beans.property.ReadOnlyListWrapper"); -ReadOnlyLongProperty = Java.type("javafx.beans.property.ReadOnlyLongProperty"); -ReadOnlyLongPropertyBase = Java.type("javafx.beans.property.ReadOnlyLongPropertyBase"); -ReadOnlyLongWrapper = Java.type("javafx.beans.property.ReadOnlyLongWrapper"); -ReadOnlyMapProperty = Java.type("javafx.beans.property.ReadOnlyMapProperty"); -ReadOnlyMapPropertyBase = Java.type("javafx.beans.property.ReadOnlyMapPropertyBase"); -ReadOnlyMapWrapper = Java.type("javafx.beans.property.ReadOnlyMapWrapper"); -ReadOnlyObjectProperty = Java.type("javafx.beans.property.ReadOnlyObjectProperty"); -ReadOnlyObjectPropertyBase = Java.type("javafx.beans.property.ReadOnlyObjectPropertyBase"); -ReadOnlyObjectWrapper = Java.type("javafx.beans.property.ReadOnlyObjectWrapper"); -ReadOnlyProperty = Java.type("javafx.beans.property.ReadOnlyProperty"); -ReadOnlySetProperty = Java.type("javafx.beans.property.ReadOnlySetProperty"); -ReadOnlySetPropertyBase = Java.type("javafx.beans.property.ReadOnlySetPropertyBase"); -ReadOnlySetWrapper = Java.type("javafx.beans.property.ReadOnlySetWrapper"); -ReadOnlyStringProperty = Java.type("javafx.beans.property.ReadOnlyStringProperty"); -ReadOnlyStringPropertyBase = Java.type("javafx.beans.property.ReadOnlyStringPropertyBase"); -ReadOnlyStringWrapper = Java.type("javafx.beans.property.ReadOnlyStringWrapper"); -SetProperty = Java.type("javafx.beans.property.SetProperty"); -SetPropertyBase = Java.type("javafx.beans.property.SetPropertyBase"); -SimpleBooleanProperty = Java.type("javafx.beans.property.SimpleBooleanProperty"); -SimpleDoubleProperty = Java.type("javafx.beans.property.SimpleDoubleProperty"); -SimpleFloatProperty = Java.type("javafx.beans.property.SimpleFloatProperty"); -SimpleIntegerProperty = Java.type("javafx.beans.property.SimpleIntegerProperty"); -SimpleListProperty = Java.type("javafx.beans.property.SimpleListProperty"); -SimpleLongProperty = Java.type("javafx.beans.property.SimpleLongProperty"); -SimpleMapProperty = Java.type("javafx.beans.property.SimpleMapProperty"); -SimpleObjectProperty = Java.type("javafx.beans.property.SimpleObjectProperty"); -SimpleSetProperty = Java.type("javafx.beans.property.SimpleSetProperty"); -SimpleStringProperty = Java.type("javafx.beans.property.SimpleStringProperty"); -StringProperty = Java.type("javafx.beans.property.StringProperty"); -StringPropertyBase = Java.type("javafx.beans.property.StringPropertyBase"); -ChangeListener = Java.type("javafx.beans.value.ChangeListener"); -ObservableBooleanValue = Java.type("javafx.beans.value.ObservableBooleanValue"); -ObservableDoubleValue = Java.type("javafx.beans.value.ObservableDoubleValue"); -ObservableFloatValue = Java.type("javafx.beans.value.ObservableFloatValue"); -ObservableIntegerValue = Java.type("javafx.beans.value.ObservableIntegerValue"); -ObservableListValue = Java.type("javafx.beans.value.ObservableListValue"); -ObservableLongValue = Java.type("javafx.beans.value.ObservableLongValue"); -ObservableMapValue = Java.type("javafx.beans.value.ObservableMapValue"); -ObservableNumberValue = Java.type("javafx.beans.value.ObservableNumberValue"); -ObservableObjectValue = Java.type("javafx.beans.value.ObservableObjectValue"); -ObservableSetValue = Java.type("javafx.beans.value.ObservableSetValue"); -ObservableStringValue = Java.type("javafx.beans.value.ObservableStringValue"); -ObservableValue = Java.type("javafx.beans.value.ObservableValue"); -ObservableValueBase = Java.type("javafx.beans.value.ObservableValueBase"); -WeakChangeListener = Java.type("javafx.beans.value.WeakChangeListener"); -WritableBooleanValue = Java.type("javafx.beans.value.WritableBooleanValue"); -WritableDoubleValue = Java.type("javafx.beans.value.WritableDoubleValue"); -WritableFloatValue = Java.type("javafx.beans.value.WritableFloatValue"); -WritableIntegerValue = Java.type("javafx.beans.value.WritableIntegerValue"); -WritableListValue = Java.type("javafx.beans.value.WritableListValue"); -WritableLongValue = Java.type("javafx.beans.value.WritableLongValue"); -WritableMapValue = Java.type("javafx.beans.value.WritableMapValue"); -WritableNumberValue = Java.type("javafx.beans.value.WritableNumberValue"); -WritableObjectValue = Java.type("javafx.beans.value.WritableObjectValue"); -WritableSetValue = Java.type("javafx.beans.value.WritableSetValue"); -WritableStringValue = Java.type("javafx.beans.value.WritableStringValue"); -WritableValue = Java.type("javafx.beans.value.WritableValue"); -WeakInvalidationListener = Java.type("javafx.beans.WeakInvalidationListener"); -WeakListener = Java.type("javafx.beans.WeakListener"); -FXCollections = Java.type("javafx.collections.FXCollections"); -ListChangeListener = Java.type("javafx.collections.ListChangeListener"); -ListChangeListener$Change = Java.type("javafx.collections.ListChangeListener$Change"); -MapChangeListener = Java.type("javafx.collections.MapChangeListener"); -MapChangeListener$Change = Java.type("javafx.collections.MapChangeListener$Change"); -ModifiableObservableListBase = Java.type("javafx.collections.ModifiableObservableListBase"); -ObservableList = Java.type("javafx.collections.ObservableList"); -ObservableListBase = Java.type("javafx.collections.ObservableListBase"); -ObservableMap = Java.type("javafx.collections.ObservableMap"); -ObservableSet = Java.type("javafx.collections.ObservableSet"); -SetChangeListener = Java.type("javafx.collections.SetChangeListener"); -SetChangeListener$Change = Java.type("javafx.collections.SetChangeListener$Change"); -WeakListChangeListener = Java.type("javafx.collections.WeakListChangeListener"); -WeakMapChangeListener = Java.type("javafx.collections.WeakMapChangeListener"); -WeakSetChangeListener = Java.type("javafx.collections.WeakSetChangeListener"); -ActionEvent = Java.type("javafx.event.ActionEvent"); -Event = Java.type("javafx.event.Event"); -EventDispatchChain = Java.type("javafx.event.EventDispatchChain"); -EventDispatcher = Java.type("javafx.event.EventDispatcher"); -EventHandler = Java.type("javafx.event.EventHandler"); -EventTarget = Java.type("javafx.event.EventTarget"); -EventType = Java.type("javafx.event.EventType"); -WeakEventHandler = Java.type("javafx.event.WeakEventHandler"); -Builder = Java.type("javafx.util.Builder"); -BuilderFactory = Java.type("javafx.util.BuilderFactory"); -Callback = Java.type("javafx.util.Callback"); -BigDecimalStringConverter = Java.type("javafx.util.converter.BigDecimalStringConverter"); -BigIntegerStringConverter = Java.type("javafx.util.converter.BigIntegerStringConverter"); -BooleanStringConverter = Java.type("javafx.util.converter.BooleanStringConverter"); -ByteStringConverter = Java.type("javafx.util.converter.ByteStringConverter"); -CharacterStringConverter = Java.type("javafx.util.converter.CharacterStringConverter"); -CurrencyStringConverter = Java.type("javafx.util.converter.CurrencyStringConverter"); -DateStringConverter = Java.type("javafx.util.converter.DateStringConverter"); -DateTimeStringConverter = Java.type("javafx.util.converter.DateTimeStringConverter"); -DefaultStringConverter = Java.type("javafx.util.converter.DefaultStringConverter"); -DoubleStringConverter = Java.type("javafx.util.converter.DoubleStringConverter"); -FloatStringConverter = Java.type("javafx.util.converter.FloatStringConverter"); -FormatStringConverter = Java.type("javafx.util.converter.FormatStringConverter"); -IntegerStringConverter = Java.type("javafx.util.converter.IntegerStringConverter"); -LongStringConverter = Java.type("javafx.util.converter.LongStringConverter"); -NumberStringConverter = Java.type("javafx.util.converter.NumberStringConverter"); -PercentageStringConverter = Java.type("javafx.util.converter.PercentageStringConverter"); -ShortStringConverter = Java.type("javafx.util.converter.ShortStringConverter"); -TimeStringConverter = Java.type("javafx.util.converter.TimeStringConverter"); -Duration = Java.type("javafx.util.Duration"); -Pair = Java.type("javafx.util.Pair"); -StringConverter = Java.type("javafx.util.StringConverter"); +function LOAD_FX_CLASSES(clsList) { + + for each (var cls in clsList) { + // Ex. Stage = Java.type("javafx.stage.Stage"); + this[cls[cls.length - 1]] = Java.type(cls.join(".")); + } +} + +(function() { + var System = Java.type("java.lang.System"); + var ZipFile = Java.type("java.util.zip.ZipFile"); + + var SUFFIX_LENGTH = ".class".length; + + try { + var jfxrtJar = new ZipFile(System.getProperty("java.home") + "/lib/ext/jfxrt.jar"); + } catch (ex) { + throw new Error("JavaFX runtime not found"); + } + + var entries = jfxrtJar.entries(); + + while (entries.hasMoreElements()) { + var entry = entries.nextElement(); + + if (entry.isDirectory()) { + continue; + } + + var name = entry.name; + + if (!name.endsWith(".class")) { + continue; + } + + name = name.substring(0, name.length - SUFFIX_LENGTH); + cls = name.split("/"); + + if (cls[0] != "javafx") { + continue; + } + + var last = cls[cls.length - 1]; + var nested = last.lastIndexOf("$"); + + // If class name ends with $nnn + if (nested != -1 && !(last.substring(nested) - 0)) { + continue; + } + + switch (cls[1]) { + case "stage": + if (cls[2] == "Stage") { + JFX_BASE_CLASSES.push(cls); + } else { + JFX_GRAPHICS_CLASSES.push(cls); + } + break; + + case "scene": + switch (cls[2]) { + case "Scene": + case "Group": + JFX_BASE_CLASSES.push(cls); + break; + + case "chart": + case "control": + JFX_CONTROLS_CLASSES.push(cls); + break; + + case "web": + JFX_WEB_CLASSES.push(cls); + break; + + case "media": + JFX_MEDIA_CLASSES.push(cls); + break; + + default: + JFX_GRAPHICS_CLASSES.push(cls); + break; + } + break; + + case "beans": + case "collections": + case "events": + case "util": + JFX_BASE_CLASSES.push(cls); + break; + + case "animation": + case "application": + case "concurrent": + case "css": + case "geometry": + JFX_GRAPHICS_CLASSES.push(cls); + break; + + case "fxml": + JFX_FXML_CLASSES.push(cls); + break; + + case "embed": + if (cls[2] == "swing") { + JFX_SWING_CLASSES.push(cls); + } else { + JFX_SWT_CLASSES.push(cls); + } + break; + } + } +})(); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js index 6a2a89c400c..ca3f284c8e3 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/controls.js @@ -23,242 +23,8 @@ * questions. */ -AreaChart = Java.type("javafx.scene.chart.AreaChart"); -AreaChartBuilder = Java.type("javafx.scene.chart.AreaChartBuilder"); -Axis = Java.type("javafx.scene.chart.Axis"); -Axis$TickMark = Java.type("javafx.scene.chart.Axis$TickMark"); -AxisBuilder = Java.type("javafx.scene.chart.AxisBuilder"); -BarChart = Java.type("javafx.scene.chart.BarChart"); -BarChartBuilder = Java.type("javafx.scene.chart.BarChartBuilder"); -BubbleChart = Java.type("javafx.scene.chart.BubbleChart"); -BubbleChartBuilder = Java.type("javafx.scene.chart.BubbleChartBuilder"); -CategoryAxis = Java.type("javafx.scene.chart.CategoryAxis"); -CategoryAxisBuilder = Java.type("javafx.scene.chart.CategoryAxisBuilder"); -Chart = Java.type("javafx.scene.chart.Chart"); -ChartBuilder = Java.type("javafx.scene.chart.ChartBuilder"); -LineChart = Java.type("javafx.scene.chart.LineChart"); -LineChartBuilder = Java.type("javafx.scene.chart.LineChartBuilder"); -NumberAxis = Java.type("javafx.scene.chart.NumberAxis"); -NumberAxis$DefaultFormatter = Java.type("javafx.scene.chart.NumberAxis$DefaultFormatter"); -NumberAxisBuilder = Java.type("javafx.scene.chart.NumberAxisBuilder"); -PieChart = Java.type("javafx.scene.chart.PieChart"); -PieChart$Data = Java.type("javafx.scene.chart.PieChart$Data"); -PieChartBuilder = Java.type("javafx.scene.chart.PieChartBuilder"); -ScatterChart = Java.type("javafx.scene.chart.ScatterChart"); -ScatterChartBuilder = Java.type("javafx.scene.chart.ScatterChartBuilder"); -StackedAreaChart = Java.type("javafx.scene.chart.StackedAreaChart"); -StackedAreaChartBuilder = Java.type("javafx.scene.chart.StackedAreaChartBuilder"); -StackedBarChart = Java.type("javafx.scene.chart.StackedBarChart"); -StackedBarChartBuilder = Java.type("javafx.scene.chart.StackedBarChartBuilder"); -ValueAxis = Java.type("javafx.scene.chart.ValueAxis"); -ValueAxisBuilder = Java.type("javafx.scene.chart.ValueAxisBuilder"); -XYChart = Java.type("javafx.scene.chart.XYChart"); -XYChart$Data = Java.type("javafx.scene.chart.XYChart$Data"); -XYChart$Series = Java.type("javafx.scene.chart.XYChart$Series"); -XYChartBuilder = Java.type("javafx.scene.chart.XYChartBuilder"); -Accordion = Java.type("javafx.scene.control.Accordion"); -AccordionBuilder = Java.type("javafx.scene.control.AccordionBuilder"); -Button = Java.type("javafx.scene.control.Button"); -ButtonBase = Java.type("javafx.scene.control.ButtonBase"); -ButtonBaseBuilder = Java.type("javafx.scene.control.ButtonBaseBuilder"); -ButtonBuilder = Java.type("javafx.scene.control.ButtonBuilder"); -Cell = Java.type("javafx.scene.control.Cell"); -CheckBoxListCell = Java.type("javafx.scene.control.cell.CheckBoxListCell"); -CheckBoxListCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxListCellBuilder"); -CheckBoxTableCell = Java.type("javafx.scene.control.cell.CheckBoxTableCell"); -CheckBoxTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTableCellBuilder"); -CheckBoxTreeCell = Java.type("javafx.scene.control.cell.CheckBoxTreeCell"); -CheckBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeCellBuilder"); -CheckBoxTreeTableCell = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCell"); -//CheckBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.CheckBoxTreeTableCellBuilder"); -ChoiceBoxListCell = Java.type("javafx.scene.control.cell.ChoiceBoxListCell"); -ChoiceBoxListCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxListCellBuilder"); -ChoiceBoxTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTableCell"); -ChoiceBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTableCellBuilder"); -ChoiceBoxTreeCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCell"); -ChoiceBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeCellBuilder"); -ChoiceBoxTreeTableCell = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCell"); -//ChoiceBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ChoiceBoxTreeTableCellBuilder"); -ComboBoxListCell = Java.type("javafx.scene.control.cell.ComboBoxListCell"); -ComboBoxListCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxListCellBuilder"); -ComboBoxTableCell = Java.type("javafx.scene.control.cell.ComboBoxTableCell"); -ComboBoxTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTableCellBuilder"); -ComboBoxTreeCell = Java.type("javafx.scene.control.cell.ComboBoxTreeCell"); -ComboBoxTreeCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeCellBuilder"); -ComboBoxTreeTableCell = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCell"); -//ComboBoxTreeTableCellBuilder = Java.type("javafx.scene.control.cell.ComboBoxTreeTableCellBuilder"); -MapValueFactory = Java.type("javafx.scene.control.cell.MapValueFactory"); -ProgressBarTableCell = Java.type("javafx.scene.control.cell.ProgressBarTableCell"); -ProgressBarTreeTableCell = Java.type("javafx.scene.control.cell.ProgressBarTreeTableCell"); -PropertyValueFactory = Java.type("javafx.scene.control.cell.PropertyValueFactory"); -PropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.PropertyValueFactoryBuilder"); -TextFieldListCell = Java.type("javafx.scene.control.cell.TextFieldListCell"); -TextFieldListCellBuilder = Java.type("javafx.scene.control.cell.TextFieldListCellBuilder"); -TextFieldTableCell = Java.type("javafx.scene.control.cell.TextFieldTableCell"); -TextFieldTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTableCellBuilder"); -TextFieldTreeCell = Java.type("javafx.scene.control.cell.TextFieldTreeCell"); -TextFieldTreeCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeCellBuilder"); -TextFieldTreeTableCell = Java.type("javafx.scene.control.cell.TextFieldTreeTableCell"); -//TextFieldTreeTableCellBuilder = Java.type("javafx.scene.control.cell.TextFieldTreeTableCellBuilder"); -TreeItemPropertyValueFactory = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactory"); -//TreeItemPropertyValueFactoryBuilder = Java.type("javafx.scene.control.cell.TreeItemPropertyValueFactoryBuilder"); -CellBuilder = Java.type("javafx.scene.control.CellBuilder"); -CheckBox = Java.type("javafx.scene.control.CheckBox"); -CheckBoxBuilder = Java.type("javafx.scene.control.CheckBoxBuilder"); -CheckBoxTreeItem = Java.type("javafx.scene.control.CheckBoxTreeItem"); -CheckBoxTreeItem$TreeModificationEvent = Java.type("javafx.scene.control.CheckBoxTreeItem$TreeModificationEvent"); -CheckBoxTreeItemBuilder = Java.type("javafx.scene.control.CheckBoxTreeItemBuilder"); -CheckMenuItem = Java.type("javafx.scene.control.CheckMenuItem"); -CheckMenuItemBuilder = Java.type("javafx.scene.control.CheckMenuItemBuilder"); -ChoiceBox = Java.type("javafx.scene.control.ChoiceBox"); -ChoiceBoxBuilder = Java.type("javafx.scene.control.ChoiceBoxBuilder"); -ColorPicker = Java.type("javafx.scene.control.ColorPicker"); -ColorPickerBuilder = Java.type("javafx.scene.control.ColorPickerBuilder"); -ComboBox = Java.type("javafx.scene.control.ComboBox"); -ComboBoxBase = Java.type("javafx.scene.control.ComboBoxBase"); -ComboBoxBaseBuilder = Java.type("javafx.scene.control.ComboBoxBaseBuilder"); -ComboBoxBuilder = Java.type("javafx.scene.control.ComboBoxBuilder"); -ContentDisplay = Java.type("javafx.scene.control.ContentDisplay"); -ContextMenu = Java.type("javafx.scene.control.ContextMenu"); -ContextMenuBuilder = Java.type("javafx.scene.control.ContextMenuBuilder"); -Control = Java.type("javafx.scene.control.Control"); -ControlBuilder = Java.type("javafx.scene.control.ControlBuilder"); -CustomMenuItem = Java.type("javafx.scene.control.CustomMenuItem"); -CustomMenuItemBuilder = Java.type("javafx.scene.control.CustomMenuItemBuilder"); -FocusModel = Java.type("javafx.scene.control.FocusModel"); -Hyperlink = Java.type("javafx.scene.control.Hyperlink"); -HyperlinkBuilder = Java.type("javafx.scene.control.HyperlinkBuilder"); -IndexedCell = Java.type("javafx.scene.control.IndexedCell"); -IndexedCellBuilder = Java.type("javafx.scene.control.IndexedCellBuilder"); -IndexRange = Java.type("javafx.scene.control.IndexRange"); -IndexRangeBuilder = Java.type("javafx.scene.control.IndexRangeBuilder"); -Label = Java.type("javafx.scene.control.Label"); -LabelBuilder = Java.type("javafx.scene.control.LabelBuilder"); -Labeled = Java.type("javafx.scene.control.Labeled"); -LabeledBuilder = Java.type("javafx.scene.control.LabeledBuilder"); -ListCell = Java.type("javafx.scene.control.ListCell"); -ListCellBuilder = Java.type("javafx.scene.control.ListCellBuilder"); -ListView = Java.type("javafx.scene.control.ListView"); -ListView$EditEvent = Java.type("javafx.scene.control.ListView$EditEvent"); -ListViewBuilder = Java.type("javafx.scene.control.ListViewBuilder"); -Menu = Java.type("javafx.scene.control.Menu"); -MenuBar = Java.type("javafx.scene.control.MenuBar"); -MenuBarBuilder = Java.type("javafx.scene.control.MenuBarBuilder"); -MenuBuilder = Java.type("javafx.scene.control.MenuBuilder"); -MenuButton = Java.type("javafx.scene.control.MenuButton"); -MenuButtonBuilder = Java.type("javafx.scene.control.MenuButtonBuilder"); -MenuItem = Java.type("javafx.scene.control.MenuItem"); -MenuItemBuilder = Java.type("javafx.scene.control.MenuItemBuilder"); -MultipleSelectionModel = Java.type("javafx.scene.control.MultipleSelectionModel"); -MultipleSelectionModelBuilder = Java.type("javafx.scene.control.MultipleSelectionModelBuilder"); -OverrunStyle = Java.type("javafx.scene.control.OverrunStyle"); -Pagination = Java.type("javafx.scene.control.Pagination"); -PaginationBuilder = Java.type("javafx.scene.control.PaginationBuilder"); -PasswordField = Java.type("javafx.scene.control.PasswordField"); -PasswordFieldBuilder = Java.type("javafx.scene.control.PasswordFieldBuilder"); -PopupControl = Java.type("javafx.scene.control.PopupControl"); -PopupControlBuilder = Java.type("javafx.scene.control.PopupControlBuilder"); -ProgressBar = Java.type("javafx.scene.control.ProgressBar"); -ProgressBarBuilder = Java.type("javafx.scene.control.ProgressBarBuilder"); -ProgressIndicator = Java.type("javafx.scene.control.ProgressIndicator"); -ProgressIndicatorBuilder = Java.type("javafx.scene.control.ProgressIndicatorBuilder"); -RadioButton = Java.type("javafx.scene.control.RadioButton"); -RadioButtonBuilder = Java.type("javafx.scene.control.RadioButtonBuilder"); -RadioMenuItem = Java.type("javafx.scene.control.RadioMenuItem"); -RadioMenuItemBuilder = Java.type("javafx.scene.control.RadioMenuItemBuilder"); -ResizeFeaturesBase = Java.type("javafx.scene.control.ResizeFeaturesBase"); -//ResizeFeaturesBaseBuilder = Java.type("javafx.scene.control.ResizeFeaturesBaseBuilder"); -ScrollBar = Java.type("javafx.scene.control.ScrollBar"); -ScrollBarBuilder = Java.type("javafx.scene.control.ScrollBarBuilder"); -ScrollPane = Java.type("javafx.scene.control.ScrollPane"); -ScrollPane$ScrollBarPolicy = Java.type("javafx.scene.control.ScrollPane$ScrollBarPolicy"); -ScrollPaneBuilder = Java.type("javafx.scene.control.ScrollPaneBuilder"); -ScrollToEvent = Java.type("javafx.scene.control.ScrollToEvent"); -SelectionMode = Java.type("javafx.scene.control.SelectionMode"); -SelectionModel = Java.type("javafx.scene.control.SelectionModel"); -Separator = Java.type("javafx.scene.control.Separator"); -SeparatorBuilder = Java.type("javafx.scene.control.SeparatorBuilder"); -SeparatorMenuItem = Java.type("javafx.scene.control.SeparatorMenuItem"); -SeparatorMenuItemBuilder = Java.type("javafx.scene.control.SeparatorMenuItemBuilder"); -SingleSelectionModel = Java.type("javafx.scene.control.SingleSelectionModel"); -Skin = Java.type("javafx.scene.control.Skin"); -SkinBase = Java.type("javafx.scene.control.SkinBase"); -//SkinBaseBuilder = Java.type("javafx.scene.control.SkinBaseBuilder"); -Skinnable = Java.type("javafx.scene.control.Skinnable"); -Slider = Java.type("javafx.scene.control.Slider"); -SliderBuilder = Java.type("javafx.scene.control.SliderBuilder"); -SortEvent = Java.type("javafx.scene.control.SortEvent"); -SplitMenuButton = Java.type("javafx.scene.control.SplitMenuButton"); -SplitMenuButtonBuilder = Java.type("javafx.scene.control.SplitMenuButtonBuilder"); -SplitPane = Java.type("javafx.scene.control.SplitPane"); -SplitPane$Divider = Java.type("javafx.scene.control.SplitPane$Divider"); -SplitPaneBuilder = Java.type("javafx.scene.control.SplitPaneBuilder"); -Tab = Java.type("javafx.scene.control.Tab"); -TabBuilder = Java.type("javafx.scene.control.TabBuilder"); -TableCell = Java.type("javafx.scene.control.TableCell"); -TableCellBuilder = Java.type("javafx.scene.control.TableCellBuilder"); -TableColumn = Java.type("javafx.scene.control.TableColumn"); -TableColumn$CellDataFeatures = Java.type("javafx.scene.control.TableColumn$CellDataFeatures"); -TableColumn$CellEditEvent = Java.type("javafx.scene.control.TableColumn$CellEditEvent"); -TableColumn$SortType = Java.type("javafx.scene.control.TableColumn$SortType"); -TableColumnBase = Java.type("javafx.scene.control.TableColumnBase"); -//TableColumnBaseBuilder = Java.type("javafx.scene.control.TableColumnBaseBuilder"); -TableColumnBuilder = Java.type("javafx.scene.control.TableColumnBuilder"); -TableFocusModel = Java.type("javafx.scene.control.TableFocusModel"); -TablePosition = Java.type("javafx.scene.control.TablePosition"); -TablePositionBase = Java.type("javafx.scene.control.TablePositionBase"); -TableRow = Java.type("javafx.scene.control.TableRow"); -TableRowBuilder = Java.type("javafx.scene.control.TableRowBuilder"); -TableSelectionModel = Java.type("javafx.scene.control.TableSelectionModel"); -//TableSelectionModelBuilder = Java.type("javafx.scene.control.TableSelectionModelBuilder"); -TableView = Java.type("javafx.scene.control.TableView"); -TableView$ResizeFeatures = Java.type("javafx.scene.control.TableView$ResizeFeatures"); -TableView$TableViewFocusModel = Java.type("javafx.scene.control.TableView$TableViewFocusModel"); -TableView$TableViewSelectionModel = Java.type("javafx.scene.control.TableView$TableViewSelectionModel"); -TableViewBuilder = Java.type("javafx.scene.control.TableViewBuilder"); -TabPane = Java.type("javafx.scene.control.TabPane"); -TabPane$TabClosingPolicy = Java.type("javafx.scene.control.TabPane$TabClosingPolicy"); -TabPaneBuilder = Java.type("javafx.scene.control.TabPaneBuilder"); -TextArea = Java.type("javafx.scene.control.TextArea"); -TextAreaBuilder = Java.type("javafx.scene.control.TextAreaBuilder"); -TextField = Java.type("javafx.scene.control.TextField"); -TextFieldBuilder = Java.type("javafx.scene.control.TextFieldBuilder"); -TextInputControl = Java.type("javafx.scene.control.TextInputControl"); -TextInputControl$Content = Java.type("javafx.scene.control.TextInputControl$Content"); -TextInputControlBuilder = Java.type("javafx.scene.control.TextInputControlBuilder"); -TitledPane = Java.type("javafx.scene.control.TitledPane"); -TitledPaneBuilder = Java.type("javafx.scene.control.TitledPaneBuilder"); -Toggle = Java.type("javafx.scene.control.Toggle"); -ToggleButton = Java.type("javafx.scene.control.ToggleButton"); -ToggleButtonBuilder = Java.type("javafx.scene.control.ToggleButtonBuilder"); -ToggleGroup = Java.type("javafx.scene.control.ToggleGroup"); -ToggleGroupBuilder = Java.type("javafx.scene.control.ToggleGroupBuilder"); -ToolBar = Java.type("javafx.scene.control.ToolBar"); -ToolBarBuilder = Java.type("javafx.scene.control.ToolBarBuilder"); -Tooltip = Java.type("javafx.scene.control.Tooltip"); -TooltipBuilder = Java.type("javafx.scene.control.TooltipBuilder"); -TreeCell = Java.type("javafx.scene.control.TreeCell"); -TreeCellBuilder = Java.type("javafx.scene.control.TreeCellBuilder"); -TreeItem = Java.type("javafx.scene.control.TreeItem"); -TreeItem$TreeModificationEvent = Java.type("javafx.scene.control.TreeItem$TreeModificationEvent"); -TreeItemBuilder = Java.type("javafx.scene.control.TreeItemBuilder"); -TreeSortMode = Java.type("javafx.scene.control.TreeSortMode"); -TreeTableCell = Java.type("javafx.scene.control.TreeTableCell"); -//TreeTableCellBuilder = Java.type("javafx.scene.control.TreeTableCellBuilder"); -TreeTableColumn = Java.type("javafx.scene.control.TreeTableColumn"); -TreeTableColumn$CellDataFeatures = Java.type("javafx.scene.control.TreeTableColumn$CellDataFeatures"); -TreeTableColumn$CellEditEvent = Java.type("javafx.scene.control.TreeTableColumn$CellEditEvent"); -TreeTableColumn$SortType = Java.type("javafx.scene.control.TreeTableColumn$SortType"); -//TreeTableColumnBuilder = Java.type("javafx.scene.control.TreeTableColumnBuilder"); -TreeTablePosition = Java.type("javafx.scene.control.TreeTablePosition"); -TreeTableRow = Java.type("javafx.scene.control.TreeTableRow"); -//TreeTableRowBuilder = Java.type("javafx.scene.control.TreeTableRowBuilder"); -TreeTableView = Java.type("javafx.scene.control.TreeTableView"); -TreeTableView$EditEvent = Java.type("javafx.scene.control.TreeTableView$EditEvent"); -TreeTableView$ResizeFeatures = Java.type("javafx.scene.control.TreeTableView$ResizeFeatures"); -TreeTableView$TreeTableViewFocusModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewFocusModel"); -TreeTableView$TreeTableViewSelectionModel = Java.type("javafx.scene.control.TreeTableView$TreeTableViewSelectionModel"); -//TreeTableViewBuilder = Java.type("javafx.scene.control.TreeTableViewBuilder"); -TreeView = Java.type("javafx.scene.control.TreeView"); -TreeView$EditEvent = Java.type("javafx.scene.control.TreeView$EditEvent"); -TreeViewBuilder = Java.type("javafx.scene.control.TreeViewBuilder"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_CONTROLS_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js index bc018a9ece3..0ce18168ce6 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/fxml.js @@ -23,8 +23,8 @@ * questions. */ -FXML = Java.type("javafx.fxml.FXML"); -FXMLLoader = Java.type("javafx.fxml.FXMLLoader"); -Initializable = Java.type("javafx.fxml.Initializable"); -JavaFXBuilderFactory = Java.type("javafx.fxml.JavaFXBuilderFactory"); -LoadException = Java.type("javafx.fxml.LoadException"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_FXML_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js index 72f55cd1926..f41661fa9e1 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/graphics.js @@ -23,409 +23,10 @@ * questions. */ -Animation = Java.type("javafx.animation.Animation"); -Animation$Status = Java.type("javafx.animation.Animation$Status"); -AnimationBuilder = Java.type("javafx.animation.AnimationBuilder"); -AnimationTimer = Java.type("javafx.animation.AnimationTimer"); -FadeTransition = Java.type("javafx.animation.FadeTransition"); -FadeTransitionBuilder = Java.type("javafx.animation.FadeTransitionBuilder"); -FillTransition = Java.type("javafx.animation.FillTransition"); -FillTransitionBuilder = Java.type("javafx.animation.FillTransitionBuilder"); -Interpolatable = Java.type("javafx.animation.Interpolatable"); -Interpolator = Java.type("javafx.animation.Interpolator"); -KeyFrame = Java.type("javafx.animation.KeyFrame"); -KeyValue = Java.type("javafx.animation.KeyValue"); -ParallelTransition = Java.type("javafx.animation.ParallelTransition"); -ParallelTransitionBuilder = Java.type("javafx.animation.ParallelTransitionBuilder"); -PathTransition = Java.type("javafx.animation.PathTransition"); -PathTransition$OrientationType = Java.type("javafx.animation.PathTransition$OrientationType"); -PathTransitionBuilder = Java.type("javafx.animation.PathTransitionBuilder"); -PauseTransition = Java.type("javafx.animation.PauseTransition"); -PauseTransitionBuilder = Java.type("javafx.animation.PauseTransitionBuilder"); -RotateTransition = Java.type("javafx.animation.RotateTransition"); -RotateTransitionBuilder = Java.type("javafx.animation.RotateTransitionBuilder"); -ScaleTransition = Java.type("javafx.animation.ScaleTransition"); -ScaleTransitionBuilder = Java.type("javafx.animation.ScaleTransitionBuilder"); -SequentialTransition = Java.type("javafx.animation.SequentialTransition"); -SequentialTransitionBuilder = Java.type("javafx.animation.SequentialTransitionBuilder"); -StrokeTransition = Java.type("javafx.animation.StrokeTransition"); -StrokeTransitionBuilder = Java.type("javafx.animation.StrokeTransitionBuilder"); -Timeline = Java.type("javafx.animation.Timeline"); -TimelineBuilder = Java.type("javafx.animation.TimelineBuilder"); -Transition = Java.type("javafx.animation.Transition"); -TransitionBuilder = Java.type("javafx.animation.TransitionBuilder"); -TranslateTransition = Java.type("javafx.animation.TranslateTransition"); -TranslateTransitionBuilder = Java.type("javafx.animation.TranslateTransitionBuilder"); -Application = Java.type("javafx.application.Application"); -Application$Parameters = Java.type("javafx.application.Application$Parameters"); -ConditionalFeature = Java.type("javafx.application.ConditionalFeature"); -HostServices = Java.type("javafx.application.HostServices"); -Platform = Java.type("javafx.application.Platform"); -Preloader = Java.type("javafx.application.Preloader"); -Preloader$ErrorNotification = Java.type("javafx.application.Preloader$ErrorNotification"); -Preloader$PreloaderNotification = Java.type("javafx.application.Preloader$PreloaderNotification"); -Preloader$ProgressNotification = Java.type("javafx.application.Preloader$ProgressNotification"); -Preloader$StateChangeNotification = Java.type("javafx.application.Preloader$StateChangeNotification"); -Preloader$StateChangeNotification$Type = Java.type("javafx.application.Preloader$StateChangeNotification$Type"); -ScheduledService = Java.type("javafx.concurrent.ScheduledService"); -Service = Java.type("javafx.concurrent.Service"); -Task = Java.type("javafx.concurrent.Task"); -Worker = Java.type("javafx.concurrent.Worker"); -Worker$State = Java.type("javafx.concurrent.Worker$State"); -WorkerStateEvent = Java.type("javafx.concurrent.WorkerStateEvent"); -CssMetaData = Java.type("javafx.css.CssMetaData"); -FontCssMetaData = Java.type("javafx.css.FontCssMetaData"); -ParsedValue = Java.type("javafx.css.ParsedValue"); -PseudoClass = Java.type("javafx.css.PseudoClass"); -SimpleStyleableBooleanProperty = Java.type("javafx.css.SimpleStyleableBooleanProperty"); -SimpleStyleableDoubleProperty = Java.type("javafx.css.SimpleStyleableDoubleProperty"); -SimpleStyleableFloatProperty = Java.type("javafx.css.SimpleStyleableFloatProperty"); -SimpleStyleableIntegerProperty = Java.type("javafx.css.SimpleStyleableIntegerProperty"); -SimpleStyleableLongProperty = Java.type("javafx.css.SimpleStyleableLongProperty"); -SimpleStyleableObjectProperty = Java.type("javafx.css.SimpleStyleableObjectProperty"); -SimpleStyleableStringProperty = Java.type("javafx.css.SimpleStyleableStringProperty"); -Styleable = Java.type("javafx.css.Styleable"); -StyleableBooleanProperty = Java.type("javafx.css.StyleableBooleanProperty"); -StyleableDoubleProperty = Java.type("javafx.css.StyleableDoubleProperty"); -StyleableFloatProperty = Java.type("javafx.css.StyleableFloatProperty"); -StyleableIntegerProperty = Java.type("javafx.css.StyleableIntegerProperty"); -StyleableLongProperty = Java.type("javafx.css.StyleableLongProperty"); -StyleableObjectProperty = Java.type("javafx.css.StyleableObjectProperty"); -StyleableProperty = Java.type("javafx.css.StyleableProperty"); -StyleableStringProperty = Java.type("javafx.css.StyleableStringProperty"); -StyleConverter = Java.type("javafx.css.StyleConverter"); -StyleOrigin = Java.type("javafx.css.StyleOrigin"); -BoundingBox = Java.type("javafx.geometry.BoundingBox"); -BoundingBoxBuilder = Java.type("javafx.geometry.BoundingBoxBuilder"); -Bounds = Java.type("javafx.geometry.Bounds"); -Dimension2D = Java.type("javafx.geometry.Dimension2D"); -Dimension2DBuilder = Java.type("javafx.geometry.Dimension2DBuilder"); -HorizontalDirection = Java.type("javafx.geometry.HorizontalDirection"); -HPos = Java.type("javafx.geometry.HPos"); -Insets = Java.type("javafx.geometry.Insets"); -InsetsBuilder = Java.type("javafx.geometry.InsetsBuilder"); -NodeOrientation = Java.type("javafx.geometry.NodeOrientation"); -Orientation = Java.type("javafx.geometry.Orientation"); -Point2D = Java.type("javafx.geometry.Point2D"); -Point2DBuilder = Java.type("javafx.geometry.Point2DBuilder"); -Point3D = Java.type("javafx.geometry.Point3D"); -Point3DBuilder = Java.type("javafx.geometry.Point3DBuilder"); -Pos = Java.type("javafx.geometry.Pos"); -Rectangle2D = Java.type("javafx.geometry.Rectangle2D"); -Rectangle2DBuilder = Java.type("javafx.geometry.Rectangle2DBuilder"); -Side = Java.type("javafx.geometry.Side"); -VerticalDirection = Java.type("javafx.geometry.VerticalDirection"); -VPos = Java.type("javafx.geometry.VPos"); -Collation = Java.type("javafx.print.Collation"); -JobSettings = Java.type("javafx.print.JobSettings"); -PageLayout = Java.type("javafx.print.PageLayout"); -PageOrientation = Java.type("javafx.print.PageOrientation"); -PageRange = Java.type("javafx.print.PageRange"); -Paper = Java.type("javafx.print.Paper"); -Paper$Units = Java.type("javafx.print.Paper$Units"); -PaperSource = Java.type("javafx.print.PaperSource"); -PrintColor = Java.type("javafx.print.PrintColor"); -Printer = Java.type("javafx.print.Printer"); -Printer$MarginType = Java.type("javafx.print.Printer$MarginType"); -PrinterAttributes = Java.type("javafx.print.PrinterAttributes"); -PrinterJob = Java.type("javafx.print.PrinterJob"); -PrinterJob$JobStatus = Java.type("javafx.print.PrinterJob$JobStatus"); -PrintQuality = Java.type("javafx.print.PrintQuality"); -PrintResolution = Java.type("javafx.print.PrintResolution"); -PrintSides = Java.type("javafx.print.PrintSides"); -AmbientLight = Java.type("javafx.scene.AmbientLight"); -//AmbientLightBuilder = Java.type("javafx.scene.AmbientLightBuilder"); -CacheHint = Java.type("javafx.scene.CacheHint"); -Camera = Java.type("javafx.scene.Camera"); -//CameraBuilder = Java.type("javafx.scene.CameraBuilder"); -Canvas = Java.type("javafx.scene.canvas.Canvas"); -CanvasBuilder = Java.type("javafx.scene.canvas.CanvasBuilder"); -GraphicsContext = Java.type("javafx.scene.canvas.GraphicsContext"); -Cursor = Java.type("javafx.scene.Cursor"); -DepthTest = Java.type("javafx.scene.DepthTest"); -Blend = Java.type("javafx.scene.effect.Blend"); -BlendBuilder = Java.type("javafx.scene.effect.BlendBuilder"); -BlendMode = Java.type("javafx.scene.effect.BlendMode"); -Bloom = Java.type("javafx.scene.effect.Bloom"); -BloomBuilder = Java.type("javafx.scene.effect.BloomBuilder"); -BlurType = Java.type("javafx.scene.effect.BlurType"); -BoxBlur = Java.type("javafx.scene.effect.BoxBlur"); -BoxBlurBuilder = Java.type("javafx.scene.effect.BoxBlurBuilder"); -ColorAdjust = Java.type("javafx.scene.effect.ColorAdjust"); -ColorAdjustBuilder = Java.type("javafx.scene.effect.ColorAdjustBuilder"); -ColorInput = Java.type("javafx.scene.effect.ColorInput"); -ColorInputBuilder = Java.type("javafx.scene.effect.ColorInputBuilder"); -DisplacementMap = Java.type("javafx.scene.effect.DisplacementMap"); -DisplacementMapBuilder = Java.type("javafx.scene.effect.DisplacementMapBuilder"); -DropShadow = Java.type("javafx.scene.effect.DropShadow"); -DropShadowBuilder = Java.type("javafx.scene.effect.DropShadowBuilder"); -Effect = Java.type("javafx.scene.effect.Effect"); -FloatMap = Java.type("javafx.scene.effect.FloatMap"); -FloatMapBuilder = Java.type("javafx.scene.effect.FloatMapBuilder"); -GaussianBlur = Java.type("javafx.scene.effect.GaussianBlur"); -GaussianBlurBuilder = Java.type("javafx.scene.effect.GaussianBlurBuilder"); -Glow = Java.type("javafx.scene.effect.Glow"); -GlowBuilder = Java.type("javafx.scene.effect.GlowBuilder"); -ImageInput = Java.type("javafx.scene.effect.ImageInput"); -ImageInputBuilder = Java.type("javafx.scene.effect.ImageInputBuilder"); -InnerShadow = Java.type("javafx.scene.effect.InnerShadow"); -InnerShadowBuilder = Java.type("javafx.scene.effect.InnerShadowBuilder"); -Light = Java.type("javafx.scene.effect.Light"); -Light$Distant = Java.type("javafx.scene.effect.Light$Distant"); -Light$Point = Java.type("javafx.scene.effect.Light$Point"); -Light$Spot = Java.type("javafx.scene.effect.Light$Spot"); -LightBuilder = Java.type("javafx.scene.effect.LightBuilder"); -Lighting = Java.type("javafx.scene.effect.Lighting"); -LightingBuilder = Java.type("javafx.scene.effect.LightingBuilder"); -MotionBlur = Java.type("javafx.scene.effect.MotionBlur"); -MotionBlurBuilder = Java.type("javafx.scene.effect.MotionBlurBuilder"); -PerspectiveTransform = Java.type("javafx.scene.effect.PerspectiveTransform"); -PerspectiveTransformBuilder = Java.type("javafx.scene.effect.PerspectiveTransformBuilder"); -Reflection = Java.type("javafx.scene.effect.Reflection"); -ReflectionBuilder = Java.type("javafx.scene.effect.ReflectionBuilder"); -SepiaTone = Java.type("javafx.scene.effect.SepiaTone"); -SepiaToneBuilder = Java.type("javafx.scene.effect.SepiaToneBuilder"); -Shadow = Java.type("javafx.scene.effect.Shadow"); -ShadowBuilder = Java.type("javafx.scene.effect.ShadowBuilder"); -//Group = Java.type("javafx.scene.Group"); -GroupBuilder = Java.type("javafx.scene.GroupBuilder"); -Image = Java.type("javafx.scene.image.Image"); -ImageView = Java.type("javafx.scene.image.ImageView"); -ImageViewBuilder = Java.type("javafx.scene.image.ImageViewBuilder"); -PixelFormat = Java.type("javafx.scene.image.PixelFormat"); -PixelFormat$Type = Java.type("javafx.scene.image.PixelFormat$Type"); -PixelReader = Java.type("javafx.scene.image.PixelReader"); -PixelWriter = Java.type("javafx.scene.image.PixelWriter"); -WritableImage = Java.type("javafx.scene.image.WritableImage"); -WritablePixelFormat = Java.type("javafx.scene.image.WritablePixelFormat"); -ImageCursor = Java.type("javafx.scene.ImageCursor"); -ImageCursorBuilder = Java.type("javafx.scene.ImageCursorBuilder"); -Clipboard = Java.type("javafx.scene.input.Clipboard"); -ClipboardContent = Java.type("javafx.scene.input.ClipboardContent"); -ClipboardContentBuilder = Java.type("javafx.scene.input.ClipboardContentBuilder"); -ContextMenuEvent = Java.type("javafx.scene.input.ContextMenuEvent"); -DataFormat = Java.type("javafx.scene.input.DataFormat"); -Dragboard = Java.type("javafx.scene.input.Dragboard"); -DragEvent = Java.type("javafx.scene.input.DragEvent"); -GestureEvent = Java.type("javafx.scene.input.GestureEvent"); -InputEvent = Java.type("javafx.scene.input.InputEvent"); -//InputEventBuilder = Java.type("javafx.scene.input.InputEventBuilder"); -InputMethodEvent = Java.type("javafx.scene.input.InputMethodEvent"); -InputMethodHighlight = Java.type("javafx.scene.input.InputMethodHighlight"); -InputMethodRequests = Java.type("javafx.scene.input.InputMethodRequests"); -InputMethodTextRun = Java.type("javafx.scene.input.InputMethodTextRun"); -//InputMethodTextRunBuilder = Java.type("javafx.scene.input.InputMethodTextRunBuilder"); -KeyCharacterCombination = Java.type("javafx.scene.input.KeyCharacterCombination"); -KeyCharacterCombinationBuilder = Java.type("javafx.scene.input.KeyCharacterCombinationBuilder"); -KeyCode = Java.type("javafx.scene.input.KeyCode"); -KeyCodeCombination = Java.type("javafx.scene.input.KeyCodeCombination"); -KeyCodeCombinationBuilder = Java.type("javafx.scene.input.KeyCodeCombinationBuilder"); -KeyCombination = Java.type("javafx.scene.input.KeyCombination"); -KeyCombination$Modifier = Java.type("javafx.scene.input.KeyCombination$Modifier"); -KeyCombination$ModifierValue = Java.type("javafx.scene.input.KeyCombination$ModifierValue"); -KeyEvent = Java.type("javafx.scene.input.KeyEvent"); -Mnemonic = Java.type("javafx.scene.input.Mnemonic"); -MnemonicBuilder = Java.type("javafx.scene.input.MnemonicBuilder"); -MouseButton = Java.type("javafx.scene.input.MouseButton"); -MouseDragEvent = Java.type("javafx.scene.input.MouseDragEvent"); -MouseEvent = Java.type("javafx.scene.input.MouseEvent"); -PickResult = Java.type("javafx.scene.input.PickResult"); -RotateEvent = Java.type("javafx.scene.input.RotateEvent"); -ScrollEvent = Java.type("javafx.scene.input.ScrollEvent"); -ScrollEvent$HorizontalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$HorizontalTextScrollUnits"); -ScrollEvent$VerticalTextScrollUnits = Java.type("javafx.scene.input.ScrollEvent$VerticalTextScrollUnits"); -SwipeEvent = Java.type("javafx.scene.input.SwipeEvent"); -TouchEvent = Java.type("javafx.scene.input.TouchEvent"); -TouchPoint = Java.type("javafx.scene.input.TouchPoint"); -TouchPoint$State = Java.type("javafx.scene.input.TouchPoint$State"); -//TouchPointBuilder = Java.type("javafx.scene.input.TouchPointBuilder"); -TransferMode = Java.type("javafx.scene.input.TransferMode"); -ZoomEvent = Java.type("javafx.scene.input.ZoomEvent"); -AnchorPane = Java.type("javafx.scene.layout.AnchorPane"); -AnchorPaneBuilder = Java.type("javafx.scene.layout.AnchorPaneBuilder"); -Background = Java.type("javafx.scene.layout.Background"); -//BackgroundBuilder = Java.type("javafx.scene.layout.BackgroundBuilder"); -BackgroundFill = Java.type("javafx.scene.layout.BackgroundFill"); -//BackgroundFillBuilder = Java.type("javafx.scene.layout.BackgroundFillBuilder"); -BackgroundImage = Java.type("javafx.scene.layout.BackgroundImage"); -//BackgroundImageBuilder = Java.type("javafx.scene.layout.BackgroundImageBuilder"); -BackgroundPosition = Java.type("javafx.scene.layout.BackgroundPosition"); -//BackgroundPositionBuilder = Java.type("javafx.scene.layout.BackgroundPositionBuilder"); -BackgroundRepeat = Java.type("javafx.scene.layout.BackgroundRepeat"); -BackgroundSize = Java.type("javafx.scene.layout.BackgroundSize"); -//BackgroundSizeBuilder = Java.type("javafx.scene.layout.BackgroundSizeBuilder"); -Border = Java.type("javafx.scene.layout.Border"); -//BorderBuilder = Java.type("javafx.scene.layout.BorderBuilder"); -BorderImage = Java.type("javafx.scene.layout.BorderImage"); -//BorderImageBuilder = Java.type("javafx.scene.layout.BorderImageBuilder"); -BorderPane = Java.type("javafx.scene.layout.BorderPane"); -BorderPaneBuilder = Java.type("javafx.scene.layout.BorderPaneBuilder"); -BorderRepeat = Java.type("javafx.scene.layout.BorderRepeat"); -BorderStroke = Java.type("javafx.scene.layout.BorderStroke"); -//BorderStrokeBuilder = Java.type("javafx.scene.layout.BorderStrokeBuilder"); -BorderStrokeStyle = Java.type("javafx.scene.layout.BorderStrokeStyle"); -//BorderStrokeStyleBuilder = Java.type("javafx.scene.layout.BorderStrokeStyleBuilder"); -BorderWidths = Java.type("javafx.scene.layout.BorderWidths"); -//BorderWidthsBuilder = Java.type("javafx.scene.layout.BorderWidthsBuilder"); -ColumnConstraints = Java.type("javafx.scene.layout.ColumnConstraints"); -ColumnConstraintsBuilder = Java.type("javafx.scene.layout.ColumnConstraintsBuilder"); -ConstraintsBase = Java.type("javafx.scene.layout.ConstraintsBase"); -CornerRadii = Java.type("javafx.scene.layout.CornerRadii"); -FlowPane = Java.type("javafx.scene.layout.FlowPane"); -FlowPaneBuilder = Java.type("javafx.scene.layout.FlowPaneBuilder"); -GridPane = Java.type("javafx.scene.layout.GridPane"); -GridPaneBuilder = Java.type("javafx.scene.layout.GridPaneBuilder"); -HBox = Java.type("javafx.scene.layout.HBox"); -HBoxBuilder = Java.type("javafx.scene.layout.HBoxBuilder"); -Pane = Java.type("javafx.scene.layout.Pane"); -PaneBuilder = Java.type("javafx.scene.layout.PaneBuilder"); -Priority = Java.type("javafx.scene.layout.Priority"); -Region = Java.type("javafx.scene.layout.Region"); -RegionBuilder = Java.type("javafx.scene.layout.RegionBuilder"); -RowConstraints = Java.type("javafx.scene.layout.RowConstraints"); -RowConstraintsBuilder = Java.type("javafx.scene.layout.RowConstraintsBuilder"); -StackPane = Java.type("javafx.scene.layout.StackPane"); -StackPaneBuilder = Java.type("javafx.scene.layout.StackPaneBuilder"); -TilePane = Java.type("javafx.scene.layout.TilePane"); -TilePaneBuilder = Java.type("javafx.scene.layout.TilePaneBuilder"); -VBox = Java.type("javafx.scene.layout.VBox"); -VBoxBuilder = Java.type("javafx.scene.layout.VBoxBuilder"); -LightBase = Java.type("javafx.scene.LightBase"); -//LightBaseBuilder = Java.type("javafx.scene.LightBaseBuilder"); -Node = Java.type("javafx.scene.Node"); -NodeBuilder = Java.type("javafx.scene.NodeBuilder"); -Color = Java.type("javafx.scene.paint.Color"); -ColorBuilder = Java.type("javafx.scene.paint.ColorBuilder"); -CycleMethod = Java.type("javafx.scene.paint.CycleMethod"); -ImagePattern = Java.type("javafx.scene.paint.ImagePattern"); -ImagePatternBuilder = Java.type("javafx.scene.paint.ImagePatternBuilder"); -LinearGradient = Java.type("javafx.scene.paint.LinearGradient"); -LinearGradientBuilder = Java.type("javafx.scene.paint.LinearGradientBuilder"); -Material = Java.type("javafx.scene.paint.Material"); -Paint = Java.type("javafx.scene.paint.Paint"); -PhongMaterial = Java.type("javafx.scene.paint.PhongMaterial"); -//PhongMaterialBuilder = Java.type("javafx.scene.paint.PhongMaterialBuilder"); -RadialGradient = Java.type("javafx.scene.paint.RadialGradient"); -RadialGradientBuilder = Java.type("javafx.scene.paint.RadialGradientBuilder"); -Stop = Java.type("javafx.scene.paint.Stop"); -StopBuilder = Java.type("javafx.scene.paint.StopBuilder"); -ParallelCamera = Java.type("javafx.scene.ParallelCamera"); -//ParallelCameraBuilder = Java.type("javafx.scene.ParallelCameraBuilder"); -Parent = Java.type("javafx.scene.Parent"); -ParentBuilder = Java.type("javafx.scene.ParentBuilder"); -PerspectiveCamera = Java.type("javafx.scene.PerspectiveCamera"); -PerspectiveCameraBuilder = Java.type("javafx.scene.PerspectiveCameraBuilder"); -PointLight = Java.type("javafx.scene.PointLight"); -//PointLightBuilder = Java.type("javafx.scene.PointLightBuilder"); -//Scene = Java.type("javafx.scene.Scene"); -SceneBuilder = Java.type("javafx.scene.SceneBuilder"); -Arc = Java.type("javafx.scene.shape.Arc"); -ArcBuilder = Java.type("javafx.scene.shape.ArcBuilder"); -ArcTo = Java.type("javafx.scene.shape.ArcTo"); -ArcToBuilder = Java.type("javafx.scene.shape.ArcToBuilder"); -ArcType = Java.type("javafx.scene.shape.ArcType"); -Box = Java.type("javafx.scene.shape.Box"); -//BoxBuilder = Java.type("javafx.scene.shape.BoxBuilder"); -Circle = Java.type("javafx.scene.shape.Circle"); -CircleBuilder = Java.type("javafx.scene.shape.CircleBuilder"); -ClosePath = Java.type("javafx.scene.shape.ClosePath"); -ClosePathBuilder = Java.type("javafx.scene.shape.ClosePathBuilder"); -CubicCurve = Java.type("javafx.scene.shape.CubicCurve"); -CubicCurveBuilder = Java.type("javafx.scene.shape.CubicCurveBuilder"); -CubicCurveTo = Java.type("javafx.scene.shape.CubicCurveTo"); -CubicCurveToBuilder = Java.type("javafx.scene.shape.CubicCurveToBuilder"); -CullFace = Java.type("javafx.scene.shape.CullFace"); -Cylinder = Java.type("javafx.scene.shape.Cylinder"); -//CylinderBuilder = Java.type("javafx.scene.shape.CylinderBuilder"); -DrawMode = Java.type("javafx.scene.shape.DrawMode"); -Ellipse = Java.type("javafx.scene.shape.Ellipse"); -EllipseBuilder = Java.type("javafx.scene.shape.EllipseBuilder"); -FillRule = Java.type("javafx.scene.shape.FillRule"); -HLineTo = Java.type("javafx.scene.shape.HLineTo"); -HLineToBuilder = Java.type("javafx.scene.shape.HLineToBuilder"); -Line = Java.type("javafx.scene.shape.Line"); -LineBuilder = Java.type("javafx.scene.shape.LineBuilder"); -LineTo = Java.type("javafx.scene.shape.LineTo"); -LineToBuilder = Java.type("javafx.scene.shape.LineToBuilder"); -Mesh = Java.type("javafx.scene.shape.Mesh"); -MeshView = Java.type("javafx.scene.shape.MeshView"); -//MeshViewBuilder = Java.type("javafx.scene.shape.MeshViewBuilder"); -MoveTo = Java.type("javafx.scene.shape.MoveTo"); -MoveToBuilder = Java.type("javafx.scene.shape.MoveToBuilder"); -Path = Java.type("javafx.scene.shape.Path"); -PathBuilder = Java.type("javafx.scene.shape.PathBuilder"); -PathElement = Java.type("javafx.scene.shape.PathElement"); -PathElementBuilder = Java.type("javafx.scene.shape.PathElementBuilder"); -Polygon = Java.type("javafx.scene.shape.Polygon"); -PolygonBuilder = Java.type("javafx.scene.shape.PolygonBuilder"); -Polyline = Java.type("javafx.scene.shape.Polyline"); -PolylineBuilder = Java.type("javafx.scene.shape.PolylineBuilder"); -QuadCurve = Java.type("javafx.scene.shape.QuadCurve"); -QuadCurveBuilder = Java.type("javafx.scene.shape.QuadCurveBuilder"); -QuadCurveTo = Java.type("javafx.scene.shape.QuadCurveTo"); -QuadCurveToBuilder = Java.type("javafx.scene.shape.QuadCurveToBuilder"); -Rectangle = Java.type("javafx.scene.shape.Rectangle"); -RectangleBuilder = Java.type("javafx.scene.shape.RectangleBuilder"); -Shape = Java.type("javafx.scene.shape.Shape"); -Shape3D = Java.type("javafx.scene.shape.Shape3D"); -//Shape3DBuilder = Java.type("javafx.scene.shape.Shape3DBuilder"); -ShapeBuilder = Java.type("javafx.scene.shape.ShapeBuilder"); -Sphere = Java.type("javafx.scene.shape.Sphere"); -//SphereBuilder = Java.type("javafx.scene.shape.SphereBuilder"); -StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); -StrokeLineJoin = Java.type("javafx.scene.shape.StrokeLineJoin"); -StrokeType = Java.type("javafx.scene.shape.StrokeType"); -SVGPath = Java.type("javafx.scene.shape.SVGPath"); -SVGPathBuilder = Java.type("javafx.scene.shape.SVGPathBuilder"); -TriangleMesh = Java.type("javafx.scene.shape.TriangleMesh"); -VLineTo = Java.type("javafx.scene.shape.VLineTo"); -VLineToBuilder = Java.type("javafx.scene.shape.VLineToBuilder"); -SnapshotParameters = Java.type("javafx.scene.SnapshotParameters"); -SnapshotParametersBuilder = Java.type("javafx.scene.SnapshotParametersBuilder"); -SnapshotResult = Java.type("javafx.scene.SnapshotResult"); -SubScene = Java.type("javafx.scene.SubScene"); -//SubSceneBuilder = Java.type("javafx.scene.SubSceneBuilder"); -Font = Java.type("javafx.scene.text.Font"); -FontBuilder = Java.type("javafx.scene.text.FontBuilder"); -FontPosture = Java.type("javafx.scene.text.FontPosture"); -FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType"); -FontWeight = Java.type("javafx.scene.text.FontWeight"); -Text = Java.type("javafx.scene.text.Text"); -TextAlignment = Java.type("javafx.scene.text.TextAlignment"); -TextBoundsType = Java.type("javafx.scene.text.TextBoundsType"); -TextBuilder = Java.type("javafx.scene.text.TextBuilder"); -TextFlow = Java.type("javafx.scene.text.TextFlow"); -//TextFlowBuilder = Java.type("javafx.scene.text.TextFlowBuilder"); -Affine = Java.type("javafx.scene.transform.Affine"); -AffineBuilder = Java.type("javafx.scene.transform.AffineBuilder"); -MatrixType = Java.type("javafx.scene.transform.MatrixType"); -NonInvertibleTransformException = Java.type("javafx.scene.transform.NonInvertibleTransformException"); -Rotate = Java.type("javafx.scene.transform.Rotate"); -RotateBuilder = Java.type("javafx.scene.transform.RotateBuilder"); -Scale = Java.type("javafx.scene.transform.Scale"); -ScaleBuilder = Java.type("javafx.scene.transform.ScaleBuilder"); -Shear = Java.type("javafx.scene.transform.Shear"); -ShearBuilder = Java.type("javafx.scene.transform.ShearBuilder"); -Transform = Java.type("javafx.scene.transform.Transform"); -//TransformBuilder = Java.type("javafx.scene.transform.TransformBuilder"); -TransformChangedEvent = Java.type("javafx.scene.transform.TransformChangedEvent"); -Translate = Java.type("javafx.scene.transform.Translate"); -TranslateBuilder = Java.type("javafx.scene.transform.TranslateBuilder"); -DirectoryChooser = Java.type("javafx.stage.DirectoryChooser"); -DirectoryChooserBuilder = Java.type("javafx.stage.DirectoryChooserBuilder"); -FileChooser = Java.type("javafx.stage.FileChooser"); -FileChooser$ExtensionFilter = Java.type("javafx.stage.FileChooser$ExtensionFilter"); -FileChooserBuilder = Java.type("javafx.stage.FileChooserBuilder"); -Modality = Java.type("javafx.stage.Modality"); -Popup = Java.type("javafx.stage.Popup"); -PopupBuilder = Java.type("javafx.stage.PopupBuilder"); -PopupWindow = Java.type("javafx.stage.PopupWindow"); -PopupWindowBuilder = Java.type("javafx.stage.PopupWindowBuilder"); -Screen = Java.type("javafx.stage.Screen"); -//Stage = Java.type("javafx.stage.Stage"); -StageBuilder = Java.type("javafx.stage.StageBuilder"); -StageStyle = Java.type("javafx.stage.StageStyle"); -Window = Java.type("javafx.stage.Window"); -WindowBuilder = Java.type("javafx.stage.WindowBuilder"); -WindowEvent = Java.type("javafx.stage.WindowEvent"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_GRAPHICS_CLASSES); + diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js index 7cc7887b3a8..29640255ba8 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/media.js @@ -23,23 +23,8 @@ * questions. */ -AudioClip = Java.type("javafx.scene.media.AudioClip"); -AudioClipBuilder = Java.type("javafx.scene.media.AudioClipBuilder"); -AudioEqualizer = Java.type("javafx.scene.media.AudioEqualizer"); -AudioSpectrumListener = Java.type("javafx.scene.media.AudioSpectrumListener"); -AudioTrack = Java.type("javafx.scene.media.AudioTrack"); -EqualizerBand = Java.type("javafx.scene.media.EqualizerBand"); -Media = Java.type("javafx.scene.media.Media"); -MediaBuilder = Java.type("javafx.scene.media.MediaBuilder"); -MediaErrorEvent = Java.type("javafx.scene.media.MediaErrorEvent"); -MediaException = Java.type("javafx.scene.media.MediaException"); -MediaException$Type = Java.type("javafx.scene.media.MediaException$Type"); -MediaMarkerEvent = Java.type("javafx.scene.media.MediaMarkerEvent"); -MediaPlayer = Java.type("javafx.scene.media.MediaPlayer"); -MediaPlayer$Status = Java.type("javafx.scene.media.MediaPlayer$Status"); -MediaPlayerBuilder = Java.type("javafx.scene.media.MediaPlayerBuilder"); -MediaView = Java.type("javafx.scene.media.MediaView"); -MediaViewBuilder = Java.type("javafx.scene.media.MediaViewBuilder"); -SubtitleTrack = Java.type("javafx.scene.media.SubtitleTrack"); -Track = Java.type("javafx.scene.media.Track"); -VideoTrack = Java.type("javafx.scene.media.VideoTrack"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_MEDIA_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js index 241205d1282..e4021af9d49 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swing.js @@ -23,7 +23,8 @@ * questions. */ -JFXPanel = Java.type("javafx.embed.swing.JFXPanel"); -JFXPanelBuilder = Java.type("javafx.embed.swing.JFXPanelBuilder"); -SwingFXUtils = Java.type("javafx.embed.swing.SwingFXUtils"); -SwingNode = Java.type("javafx.embed.swing.SwingNode"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_SWING_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js index 82197c71198..144bcd5de71 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/swt.js @@ -23,7 +23,8 @@ * questions. */ -CustomTransfer = Java.type("javafx.embed.swt.CustomTransfer"); -//CustomTransferBuilder = Java.type("javafx.embed.swt.CustomTransferBuilder"); -FXCanvas = Java.type("javafx.embed.swt.FXCanvas"); -SWTFXUtils = Java.type("javafx.embed.swt.SWTFXUtils"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_SWT_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js index 606c3c315a9..fa66cb25788 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/fx/web.js @@ -23,14 +23,8 @@ * questions. */ -HTMLEditor = Java.type("javafx.scene.web.HTMLEditor"); -//HTMLEditorBuilder = Java.type("javafx.scene.web.HTMLEditorBuilder"); -PopupFeatures = Java.type("javafx.scene.web.PopupFeatures"); -PromptData = Java.type("javafx.scene.web.PromptData"); -//PromptDataBuilder = Java.type("javafx.scene.web.PromptDataBuilder"); -WebEngine = Java.type("javafx.scene.web.WebEngine"); -WebEngineBuilder = Java.type("javafx.scene.web.WebEngineBuilder"); -WebEvent = Java.type("javafx.scene.web.WebEvent"); -WebHistory = Java.type("javafx.scene.web.WebHistory"); -WebView = Java.type("javafx.scene.web.WebView"); -WebViewBuilder = Java.type("javafx.scene.web.WebViewBuilder"); +if (!this.JFX_BASE_CLASSES) { + load("fx:base.js") +} + +LOAD_FX_CLASSES(JFX_WEB_CLASSES); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js index 60bdc7b1ab0..6b934ad4b00 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js @@ -137,17 +137,6 @@ Object.defineProperty(Object.prototype, "__lookupSetter__", { } }); -// Object.prototype.__proto__ (read-only) -Object.defineProperty(Object.prototype, "__proto__", { - configurable: true, enumerable: false, - get: function() { - return Object.getPrototypeOf(this); - }, - set: function(x) { - Object.setPrototypeOf(this, x); - } -}); - // Object.prototype.toSource Object.defineProperty(Object.prototype, "toSource", { configurable: true, enumerable: false, writable: true, diff --git a/nashorn/test/script/basic/8024180/global_var_delete.js b/nashorn/test/script/basic/8024180/global_var_delete.js new file mode 100644 index 00000000000..f099dd33f87 --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_delete.js @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + + +this.x = 44; + +function func() { + with({ }) { + print(x); + } +} + +func(); + +// delete global 'x' +delete this.x; + +try { + func(); +} catch(e) { + // expect ReferenceError + print(e); +} diff --git a/nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED b/nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED new file mode 100644 index 00000000000..7e54b9e6a3c --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_delete.js.EXPECTED @@ -0,0 +1,2 @@ +44 +ReferenceError: "x" is not defined diff --git a/nashorn/test/script/basic/8024180/global_var_shadow.js b/nashorn/test/script/basic/8024180/global_var_shadow.js new file mode 100644 index 00000000000..5ba5f5e2d1d --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_shadow.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// global variable is shadowed by with 'expression' property +var user = { name: 'foo' }; + +function func(locals) { + with (locals) { + print(user.name); + } +} + +// global user.name 'foo' printed +func({}); + +// local user.name 'toto' printed +func({ user: { name: 'toto' } }); + diff --git a/nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED b/nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED new file mode 100644 index 00000000000..7f1a102b9cc --- /dev/null +++ b/nashorn/test/script/basic/8024180/global_var_shadow.js.EXPECTED @@ -0,0 +1,2 @@ +foo +toto diff --git a/nashorn/test/script/basic/8024180/scope_no_such_prop.js b/nashorn/test/script/basic/8024180/scope_no_such_prop.js new file mode 100644 index 00000000000..5973c469e0d --- /dev/null +++ b/nashorn/test/script/basic/8024180/scope_no_such_prop.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// __noSuchProperty__ defined here confuses 'with' +// results in ReferenceError even when 'with' expression has +// the property + +load("nashorn:mozilla_compat.js") + +function func(locals) { + with (locals) { + print(user.name); + } +} + +try { + func({}); +} catch (e) { + print(e); +} + +// 'toto' expected in the call below +func({ user: { name: 'toto' } }); + diff --git a/nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED b/nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED new file mode 100644 index 00000000000..ad4d247ea47 --- /dev/null +++ b/nashorn/test/script/basic/8024180/scope_no_such_prop.js.EXPECTED @@ -0,0 +1,2 @@ +ReferenceError: user is not defined +toto diff --git a/nashorn/test/script/basic/8024180/with_expr_prop_add.js b/nashorn/test/script/basic/8024180/with_expr_prop_add.js new file mode 100644 index 00000000000..7c3b3a546fb --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_prop_add.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +var obj = {}; +var x = "global x"; + +// adding property to 'with' xpression object should reflect +// as variable inside the 'with' block. +function func() { + with(obj) { + for (i = 0; i < 2; i++) { + print(x); + if (i == 0) { + obj.x = "obj.x"; + } + } + } +} + +func(); diff --git a/nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED b/nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED new file mode 100644 index 00000000000..4139e361961 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_prop_add.js.EXPECTED @@ -0,0 +1,2 @@ +global x +obj.x diff --git a/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js new file mode 100644 index 00000000000..a6a17e7071b --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +var p = { }; +var obj = Object.create(p); + +var x = "global x"; + +// adding property to __proto__ of 'with' expression should +// reflect as a variable immediately. +function func() { + with(obj) { + for (i = 0; i < 2; i++) { + print(x); + if (i == 0) { + p.x = "p.x"; + } + } + } +} + +func(); diff --git a/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED new file mode 100644 index 00000000000..aa6d3681c18 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_expr_proto_prop_add.js.EXPECTED @@ -0,0 +1,2 @@ +global x +p.x diff --git a/nashorn/test/script/basic/8024180/with_java_object.js b/nashorn/test/script/basic/8024180/with_java_object.js new file mode 100644 index 00000000000..32db2a5c3e0 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_java_object.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024180: Incorrect handling of expression and parent scope in 'with' statements + * + * @test + * @run + */ + +// TypeError for with expression being non script object +try { + with(new java.lang.Object()) {} +} catch (e) { + print(e); +} diff --git a/nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED b/nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED new file mode 100644 index 00000000000..3f0facfade1 --- /dev/null +++ b/nashorn/test/script/basic/8024180/with_java_object.js.EXPECTED @@ -0,0 +1 @@ +TypeError: Cannot apply "with" to non script object diff --git a/nashorn/test/script/basic/JDK-8023368.js b/nashorn/test/script/basic/JDK-8023368.js index 9f32805caa8..da034dbc566 100644 --- a/nashorn/test/script/basic/JDK-8023368.js +++ b/nashorn/test/script/basic/JDK-8023368.js @@ -28,8 +28,6 @@ * @run */ -load("nashorn:mozilla_compat.js"); - // function to force same callsites function check(obj) { print(obj.func()); diff --git a/nashorn/test/script/basic/JDK-8023368.js.EXPECTED b/nashorn/test/script/basic/JDK-8023368.js.EXPECTED index 4ca8d077d38..c116a6b7c10 100644 --- a/nashorn/test/script/basic/JDK-8023368.js.EXPECTED +++ b/nashorn/test/script/basic/JDK-8023368.js.EXPECTED @@ -4,15 +4,15 @@ hello Func.prototype.func hello [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 [object Object] -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 new object.toString -obj.__proto__.func @ 57 +obj.__proto__.func @ 55 344 new object.toString diff --git a/nashorn/test/script/basic/JDK-8024120.js b/nashorn/test/script/basic/JDK-8024120.js new file mode 100644 index 00000000000..0ac4ff98c15 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024120.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024120: Setting __proto__ to null removes the __proto__ property + * + * @test + * @run + */ + +var obj = {}; + +obj.__proto__ = null; + +if (obj.__proto__ !== null || typeof(obj.__proto__) != 'object') { + fail("obj.__proto__ is expected to be null"); +} + +var p = Object.getPrototypeOf(obj); +if (p !== null || typeof(p) != 'object') { + fail("Object.getPrototypeOf(obj) is expected to be null"); +} diff --git a/nashorn/test/script/basic/JDK-8024174.js b/nashorn/test/script/basic/JDK-8024174.js new file mode 100644 index 00000000000..5fd48e17bc3 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024174.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024174: Setting __proto__ property in Object literal should be supported * + * @test + * @run + */ + +var p = { foo: function() { print("p.foo"); } }; + +var obj = { + __proto__ : p, + bar: 44 +}; + +if (obj.__proto__ !== p || Object.getPrototypeOf(obj) !== p) { + fail("obj.__proto__ was not set inside literal"); +} + +if (typeof(obj.foo) !== 'function' || obj.foo !== p.foo) { + fail("'obj' failed to inherit 'foo' from 'p'"); +} + +var obj2 = { + __proto__: null +}; + +if (obj2.__proto__ !== null || Object.getPrototypeOf(obj2) !== null) { + fail("obj2.__proto__ was not set to null inside literal"); +} diff --git a/nashorn/test/script/basic/JDK-8024255.js b/nashorn/test/script/basic/JDK-8024255.js new file mode 100644 index 00000000000..54022a5cd1d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024255.js @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024255: When a keyword is used as object property name, the property can not be deleted + * + * @test + * @run + */ + +function check(obj, name) { + var desc = Object.getOwnPropertyDescriptor(obj, name); + if (! desc.configurable) { + fail("Property " + name + " is not configurable"); + } + + if (! (delete obj[name])) { + fail("Property " + name + " can not be deleted"); + } +} + +var obj = { + default: 344, + in: 'hello', + if: false, + class: 4.223 +} + +for (var p in obj) { + check(obj, p); +} diff --git a/nashorn/test/script/basic/JDK-8024512.js b/nashorn/test/script/basic/JDK-8024512.js new file mode 100644 index 00000000000..c03ba212c14 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024512.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024512: Regex /[^\[]/ doesn't match + * + * @test + * @run + */ + +print("[M]".match(/(\[[^\[]*\])/)); +print("[[]".match(/(\[[^\[]*\])/)); + +print("[M]".match(/(\[[^\[^]*\])/)); +print("[[]".match(/(\[[^\[^]*\])/)); +print("[^]".match(/(\[[^\[^]*\])/)); + +print("[M]".match(/(\[[^\[]\])/)); +print("[[]".match(/(\[[^\[]\])/)); + +print("[M]".match(/(\[[^\[^]\])/)); +print("[[]".match(/(\[[^\[^]\])/)); +print("[^]".match(/(\[[^\[^]\])/)); + +print("M".match(/[^\[]/)); +print("[".match(/[^\[]/)); +print("^".match(/[^\[]/)); + +// Repeat above without escaping inner square bracket +print("[M]".match(/(\[[^[]\])/)); +print("[[]".match(/(\[[^[]\])/)); + +print("[M]".match(/(\[[^[^]\])/)); +print("[[]".match(/(\[[^[^]\])/)); +print("[^]".match(/(\[[^[^]\])/)); + +print("M".match(/[^[]/)); +print("[".match(/[^[]/)); +print("^".match(/[^[]/)); diff --git a/nashorn/test/script/basic/JDK-8024512.js.EXPECTED b/nashorn/test/script/basic/JDK-8024512.js.EXPECTED new file mode 100644 index 00000000000..9bb84de91dc --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024512.js.EXPECTED @@ -0,0 +1,21 @@ +[M],[M] +[],[] +[M],[M] +[],[] +null +[M],[M] +null +[M],[M] +null +null +M +null +^ +[M],[M] +null +[M],[M] +null +null +M +null +^ diff --git a/nashorn/test/script/basic/JDK-8024619.js b/nashorn/test/script/basic/JDK-8024619.js new file mode 100644 index 00000000000..064e0d7b676 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024619.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024619: JDBC java.sql.DriverManager is not usable from JS script + * + * @test + * @run + */ + +var DriverManager = Java.type("java.sql.DriverManager"); +var e = DriverManager.getDrivers(); + +var driverFound = false; +// check for Nashorn SQL driver +while (e.hasMoreElements()) { + var driver = e.nextElement(); + if (driver.acceptsURL("jdbc:nashorn:")) { + driverFound = true; + break; + } +} + +if (! driverFound) { + fail("Nashorn JDBC Driver not found!"); +} diff --git a/nashorn/test/script/basic/JDK-8024846.js b/nashorn/test/script/basic/JDK-8024846.js new file mode 100644 index 00000000000..ccdf8fcc9b6 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024846.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024846: keep separate internal arguments variable + * + * @test + */ + +function f() { print(arguments); } + +function func(obj) { + var arguments = obj; + for (var i in arguments) { + } + return obj; +} diff --git a/nashorn/test/script/basic/JDK-8024847.js b/nashorn/test/script/basic/JDK-8024847.js new file mode 100644 index 00000000000..4a671ecd9f0 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024847.js @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8024847: Java.to should accept mirror and external JSObjects as array-like objects as well + * + * @test + * @run + */ + +var global = loadWithNewGlobal({ name: "test", script:"this" }); +var arr = new global.Array(2, 4, 6, 8); +var jarr = Java.to(arr, "int[]"); +for (var i in jarr) { + print(jarr[i]); +} + +arr = null; +jarr = null; + +// external JSObjects +var JSObject = Java.type("jdk.nashorn.api.scripting.JSObject"); +var arr = new JSObject() { + getMember: function(name) { + return name == "length"? 4 : undefined; + }, + + hasMember: function(name) { + return name == "length"; + }, + + getSlot: function(idx) { + return idx*idx; + }, + + hasSlot: function(idx) { + return true; + } +}; + +var jarr = Java.to(arr, "int[]"); +for (var i in jarr) { + print(jarr[i]); +} + +arr = null; +jarr = null; + +// List conversion +var arr = global.Array("hello", "world"); +var jlist = Java.to(arr, java.util.List); +print(jlist instanceof java.util.List); +print(jlist); + +arr = null; +jlist = null; + +// external JSObject +var __array__ = [ "nashorn", "js" ]; + +var obj = new JSObject() { + + hasMember: function(name) { + return name in __array__; + }, + + hasSlot: function(idx) { + return idx in __array__; + }, + + getMember: function(name) { + return __array__[name]; + }, + + getSlot: function(idx) { + return __array__[idx]; + } +} + +var jlist = Java.to(obj, java.util.List); +print(jlist instanceof java.util.List); +print(jlist); diff --git a/nashorn/test/script/basic/JDK-8024847.js.EXPECTED b/nashorn/test/script/basic/JDK-8024847.js.EXPECTED new file mode 100644 index 00000000000..015183a02a9 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8024847.js.EXPECTED @@ -0,0 +1,12 @@ +2 +4 +6 +8 +0 +1 +4 +9 +true +[hello, world] +true +[nashorn, js] diff --git a/nashorn/test/script/basic/NASHORN-737.js b/nashorn/test/script/basic/NASHORN-737.js index 44169d0435f..3db48918df1 100644 --- a/nashorn/test/script/basic/NASHORN-737.js +++ b/nashorn/test/script/basic/NASHORN-737.js @@ -30,4 +30,4 @@ load("nashorn:parser.js"); var ast = parse("label: while(true) break label;"); -print(JSON.stringify(ast)); +print(JSON.stringify(ast, null, " ")); diff --git a/nashorn/test/script/basic/NASHORN-737.js.EXPECTED b/nashorn/test/script/basic/NASHORN-737.js.EXPECTED index 8f828342948..77c796579f4 100644 --- a/nashorn/test/script/basic/NASHORN-737.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-737.js.EXPECTED @@ -1 +1,36 @@ -{"type":"Program","rest":null,"body":[{"type":"LabeledStatement","label":{"type":"Identifier","name":"label"},"body":{"type":"BlockStatement","body":[{"type":"WhileStatement","test":{"type":"Literal","value":true},"block":{"type":"BlockStatement","body":[{"type":"BreakStatement","label":"label"}]}}]}}]} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "label" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "label" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/circular_proto.js b/nashorn/test/script/basic/circular_proto.js index 5ae8f9cd03b..b381b7cf2d7 100644 --- a/nashorn/test/script/basic/circular_proto.js +++ b/nashorn/test/script/basic/circular_proto.js @@ -29,7 +29,6 @@ */ // check that we cannot create __proto__ cycle -load("nashorn:mozilla_compat.js"); var obj = {}; var obj2 = Object.create(obj); diff --git a/nashorn/test/script/basic/nonextensible_proto_assign.js b/nashorn/test/script/basic/nonextensible_proto_assign.js index 0240420d332..10ce4f53e27 100644 --- a/nashorn/test/script/basic/nonextensible_proto_assign.js +++ b/nashorn/test/script/basic/nonextensible_proto_assign.js @@ -28,8 +28,6 @@ * @run */ -load("nashorn:mozilla_compat.js") - // check that we cannot assign to __proto__ of a non-extensible object try { var obj = {} diff --git a/nashorn/test/script/basic/parser/assignmentExpr.js b/nashorn/test/script/basic/parser/assignmentExpr.js new file mode 100644 index 00000000000..231e19fd9b1 --- /dev/null +++ b/nashorn/test/script/basic/parser/assignmentExpr.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check assignment e xyzpressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("xyz = 314"); +printParse("xyz += 314"); +printParse("xyz -= 314"); +printParse("xyz *= 314"); +printParse("xyz /= 314"); +printParse("xyz %= 314"); +printParse("xyz <<= 314"); +printParse("xyz >>= 314"); +printParse("xyz >>>= 314"); +printParse("xyz &= 314"); +printParse("xyz ^= 314"); +printParse("xyz |= 314"); diff --git a/nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED b/nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED new file mode 100644 index 00000000000..da6793afa55 --- /dev/null +++ b/nashorn/test/script/basic/parser/assignmentExpr.js.EXPECTED @@ -0,0 +1,240 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "+=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "-=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "*=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "/=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "%=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "<<=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": ">>=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": ">>>=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "&=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "^=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "|=", + "left": { + "type": "Identifier", + "name": "xyz" + }, + "right": { + "type": "Literal", + "value": 314 + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/binaryExpr.js b/nashorn/test/script/basic/parser/binaryExpr.js new file mode 100644 index 00000000000..a2b761da2f1 --- /dev/null +++ b/nashorn/test/script/basic/parser/binaryExpr.js @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check binary operators. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a * b") +printParse("a / b"); +printParse("a % b"); +printParse("a + b"); +printParse("a - b"); +printParse("a << b"); +printParse("a >> b"); +printParse("a >>> b"); +printParse("a < b"); +printParse("a > b"); +printParse("a <= b"); +printParse("a >= b"); +printParse("a instanceof b"); +printParse("a == b"); +printParse("a != b"); +printParse("a === b"); +printParse("a !== b"); +printParse("a & b"); +printParse("a ^ b"); +printParse("a | b"); +printParse("a && b"); +printParse("a || b"); diff --git a/nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED b/nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED new file mode 100644 index 00000000000..dd75f4b6096 --- /dev/null +++ b/nashorn/test/script/basic/parser/binaryExpr.js.EXPECTED @@ -0,0 +1,440 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "*", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "/", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "%", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "-", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<<", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">>", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">>>", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": ">=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "==", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "!=", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "===", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "!==", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "&", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "^", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "|", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "LogicalExpression", + "operator": "&&", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "LogicalExpression", + "operator": "||", + "left": { + "type": "Identifier", + "name": "a" + }, + "right": { + "type": "Identifier", + "name": "b" + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/breakStat.js b/nashorn/test/script/basic/parser/breakStat.js new file mode 100644 index 00000000000..1b16cc2ce75 --- /dev/null +++ b/nashorn/test/script/basic/parser/breakStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check 'break' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while (true) { break; }"); +printParse("loop: { while (true) { break loop } }"); +printParse("loop: { for (;;) { break loop } }"); diff --git a/nashorn/test/script/basic/parser/breakStat.js.EXPECTED b/nashorn/test/script/basic/parser/breakStat.js.EXPECTED new file mode 100644 index 00000000000..1d9fd079810 --- /dev/null +++ b/nashorn/test/script/basic/parser/breakStat.js.EXPECTED @@ -0,0 +1,92 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "loop" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "loop" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "loop" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "loop" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/condExpr.js b/nashorn/test/script/basic/parser/condExpr.js new file mode 100644 index 00000000000..3644ff35e84 --- /dev/null +++ b/nashorn/test/script/basic/parser/condExpr.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check ternary operator. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a? b : c"); diff --git a/nashorn/test/script/basic/parser/condExpr.js.EXPECTED b/nashorn/test/script/basic/parser/condExpr.js.EXPECTED new file mode 100644 index 00000000000..75c486fa85f --- /dev/null +++ b/nashorn/test/script/basic/parser/condExpr.js.EXPECTED @@ -0,0 +1,23 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ConditionalExpression", + "test": { + "type": "Identifier", + "name": "a" + }, + "consequent": { + "type": "Identifier", + "name": "b" + }, + "alternate": { + "type": "Identifier", + "name": "c" + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/continueStat.js b/nashorn/test/script/basic/parser/continueStat.js new file mode 100644 index 00000000000..22ddadd44e6 --- /dev/null +++ b/nashorn/test/script/basic/parser/continueStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check 'continue' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while (true) { continue; }"); +printParse("begin: { while (true) { continue begin; } }"); +printParse("start: { for(;;) { continue start; } }"); diff --git a/nashorn/test/script/basic/parser/continueStat.js.EXPECTED b/nashorn/test/script/basic/parser/continueStat.js.EXPECTED new file mode 100644 index 00000000000..cfd3114db3c --- /dev/null +++ b/nashorn/test/script/basic/parser/continueStat.js.EXPECTED @@ -0,0 +1,92 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "start" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ContinueStatement", + "label": { + "type": "Identifier", + "name": "start" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/debuggerStat.js b/nashorn/test/script/basic/parser/debuggerStat.js new file mode 100644 index 00000000000..60eab78fff0 --- /dev/null +++ b/nashorn/test/script/basic/parser/debuggerStat.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check debugger statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("debugger"); diff --git a/nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED b/nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED new file mode 100644 index 00000000000..7b954fc30ee --- /dev/null +++ b/nashorn/test/script/basic/parser/debuggerStat.js.EXPECTED @@ -0,0 +1,8 @@ +{ + "type": "Program", + "body": [ + { + "type": "DebuggerStatement" + } + ] +} diff --git a/nashorn/test/script/basic/parser/functions.js b/nashorn/test/script/basic/parser/functions.js new file mode 100644 index 00000000000..7b624b554be --- /dev/null +++ b/nashorn/test/script/basic/parser/functions.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check 'function' statements and expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("function hello() { print('hello') }") +printParse("function hello(a) { print(a) }") +printParse("function hello(a, b) { print(a, b) }") +printParse("var hello = function() { print('hello') };") +printParse("var hello = function hello() { print('hello') };") +printParse("(function(){})") +printParse("function test() { 'use strict' }"); diff --git a/nashorn/test/script/basic/parser/functions.js.EXPECTED b/nashorn/test/script/basic/parser/functions.js.EXPECTED new file mode 100644 index 00000000000..59451d57942 --- /dev/null +++ b/nashorn/test/script/basic/parser/functions.js.EXPECTED @@ -0,0 +1,279 @@ +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [ + { + "type": "Identifier", + "name": "a" + } + ], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "hello" + }, + "init": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "hello" + }, + "init": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "hello" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "test" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} diff --git a/nashorn/test/script/basic/parser/ifStat.js b/nashorn/test/script/basic/parser/ifStat.js new file mode 100644 index 00000000000..5d1566686c2 --- /dev/null +++ b/nashorn/test/script/basic/parser/ifStat.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check 'if' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("if (js) { nashorn() }"); +printParse("if (js) { nashorn() } else { java() }"); diff --git a/nashorn/test/script/basic/parser/ifStat.js.EXPECTED b/nashorn/test/script/basic/parser/ifStat.js.EXPECTED new file mode 100644 index 00000000000..3897dc14fca --- /dev/null +++ b/nashorn/test/script/basic/parser/ifStat.js.EXPECTED @@ -0,0 +1,73 @@ +{ + "type": "Program", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "js" + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "nashorn" + }, + "arguments": [] + } + } + ] + }, + "alternate": null + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "IfStatement", + "test": { + "type": "Identifier", + "name": "js" + }, + "consequent": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "nashorn" + }, + "arguments": [] + } + } + ] + }, + "alternate": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "java" + }, + "arguments": [] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/labelledStat.js b/nashorn/test/script/basic/parser/labelledStat.js new file mode 100644 index 00000000000..25829a4a755 --- /dev/null +++ b/nashorn/test/script/basic/parser/labelledStat.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Test for labelled statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("begin: { for (;;) break begin }"); +printParse("begin: { while (true) break begin }"); diff --git a/nashorn/test/script/basic/parser/labelledStat.js.EXPECTED b/nashorn/test/script/basic/parser/labelledStat.js.EXPECTED new file mode 100644 index 00000000000..fc5f37e8a3b --- /dev/null +++ b/nashorn/test/script/basic/parser/labelledStat.js.EXPECTED @@ -0,0 +1,71 @@ +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ForStatement", + "init": null, + "test": null, + "update": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "LabeledStatement", + "label": { + "type": "Identifier", + "name": "begin" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "BreakStatement", + "label": { + "type": "Identifier", + "name": "begin" + } + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/lhsExpr.js b/nashorn/test/script/basic/parser/lhsExpr.js new file mode 100644 index 00000000000..68f4d6c3c46 --- /dev/null +++ b/nashorn/test/script/basic/parser/lhsExpr.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check left-hand-side expressions + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("a[3]"); +printParse("a[b]"); +printParse("a['foo']"); +printParse("obj.foo"); +printParse("obj.foo.bar"); +printParse("new Type"); +printParse("new Type()"); +printParse("new Type(a, 'hello')"); +printParse("new obj.Type"); +printParse("new obj.Type()"); +printParse("new obj.Type(a, 'hello')"); +printParse("foo()") +printParse("obj.foo()"); +printParse("foo(a,b)"); +printParse("obj.foo(a, b)"); diff --git a/nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED b/nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED new file mode 100644 index 00000000000..e61c6c8fc6a --- /dev/null +++ b/nashorn/test/script/basic/parser/lhsExpr.js.EXPECTED @@ -0,0 +1,344 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Literal", + "value": 3 + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Identifier", + "name": "b" + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "a" + }, + "property": { + "type": "Literal", + "value": "foo" + }, + "computed": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "MemberExpression", + "object": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "property": { + "type": "Identifier", + "name": "bar" + }, + "computed": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "Type" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "NewExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "Type" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "foo" + }, + "computed": false + }, + "arguments": [ + { + "type": "Identifier", + "name": "a" + }, + { + "type": "Identifier", + "name": "b" + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/loopStat.js b/nashorn/test/script/basic/parser/loopStat.js new file mode 100644 index 00000000000..ba705568e8e --- /dev/null +++ b/nashorn/test/script/basic/parser/loopStat.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests for loop statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("while(true) { print('hello') }") +printParse("do { print('hello') } while(true)") +printParse("for (i in obj) { print(obj[i]) }") +printParse("for each (i in obj) { print(i) }") +printParse("for (i = 0; i < 10; i++) { print(i) }") diff --git a/nashorn/test/script/basic/parser/loopStat.js.EXPECTED b/nashorn/test/script/basic/parser/loopStat.js.EXPECTED new file mode 100644 index 00000000000..fd8ef838afc --- /dev/null +++ b/nashorn/test/script/basic/parser/loopStat.js.EXPECTED @@ -0,0 +1,212 @@ +{ + "type": "Program", + "body": [ + { + "type": "WhileStatement", + "test": { + "type": "Literal", + "value": true + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "DoWhileStatement", + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Literal", + "value": "hello" + } + ] + } + } + ] + }, + "test": { + "type": "Literal", + "value": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForInStatement", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Identifier", + "name": "obj" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "MemberExpression", + "object": { + "type": "Identifier", + "name": "obj" + }, + "property": { + "type": "Identifier", + "name": "i" + }, + "computed": true + } + ] + } + } + ] + }, + "each": false + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForInStatement", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Identifier", + "name": "obj" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "i" + } + ] + } + } + ] + }, + "each": true + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ForStatement", + "init": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Literal", + "value": 0 + } + }, + "test": { + "type": "BinaryExpression", + "operator": "<", + "left": { + "type": "Identifier", + "name": "i" + }, + "right": { + "type": "Literal", + "value": 10 + } + }, + "update": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "i" + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "print" + }, + "arguments": [ + { + "type": "Identifier", + "name": "i" + } + ] + } + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/objectLitExpr.js b/nashorn/test/script/basic/parser/objectLitExpr.js new file mode 100644 index 00000000000..bdecc7fa691 --- /dev/null +++ b/nashorn/test/script/basic/parser/objectLitExpr.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check assignment e xyzpressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("obj = {}"); +printParse("p = { x: 10, y: 2 }"); +printParse("p = { 'x': 10, 'y': 2 }"); +printParse("p = { get x() { return xValue }, get y() { return yValue } }"); diff --git a/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED new file mode 100644 index 00000000000..067c506ab95 --- /dev/null +++ b/nashorn/test/script/basic/parser/objectLitExpr.js.EXPECTED @@ -0,0 +1,189 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "obj" + }, + "right": { + "type": "ObjectExpression", + "properties": [] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "Literal", + "value": 10 + }, + "kind": "init" + }, + { + "key": { + "type": "Identifier", + "name": "y" + }, + "value": { + "type": "Literal", + "value": 2 + }, + "kind": "init" + } + ] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Literal", + "value": "x" + }, + "value": { + "type": "Literal", + "value": 10 + }, + "kind": "init" + }, + { + "key": { + "type": "Literal", + "value": "y" + }, + "value": { + "type": "Literal", + "value": 2 + }, + "kind": "init" + } + ] + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "p" + }, + "right": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "get x" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "xValue" + } + } + ] + }, + "generator": false, + "expression": false + }, + "kind": "get" + }, + { + "key": { + "type": "Identifier", + "name": "y" + }, + "value": { + "type": "FunctionExpression", + "id": { + "type": "Identifier", + "name": "get y" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "yValue" + } + } + ] + }, + "generator": false, + "expression": false + }, + "kind": "get" + } + ] + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/parenExpr.js b/nashorn/test/script/basic/parser/parenExpr.js new file mode 100644 index 00000000000..2d52a023034 --- /dev/null +++ b/nashorn/test/script/basic/parser/parenExpr.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests for parenthesis expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("(2) + (1) + 4"); +printParse("3 + (7) << (5)"); diff --git a/nashorn/test/script/basic/parser/parenExpr.js.EXPECTED b/nashorn/test/script/basic/parser/parenExpr.js.EXPECTED new file mode 100644 index 00000000000..1e4a2306c71 --- /dev/null +++ b/nashorn/test/script/basic/parser/parenExpr.js.EXPECTED @@ -0,0 +1,56 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 2 + }, + "right": { + "type": "Literal", + "value": 1 + } + }, + "right": { + "type": "Literal", + "value": 4 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "<<", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 3 + }, + "right": { + "type": "Literal", + "value": 7 + } + }, + "right": { + "type": "Literal", + "value": 5 + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/primaryExpr.js b/nashorn/test/script/basic/parser/primaryExpr.js new file mode 100644 index 00000000000..950c47f3ea8 --- /dev/null +++ b/nashorn/test/script/basic/parser/primaryExpr.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check primary expressions. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("this"); +printParse("foo"); +printParse("null"); +printParse("true"); +printParse("false"); +printParse("33"); +printParse("3.14"); +printParse("(10 + 3)*2"); +printParse("({})"); +printParse("({ x: 3 })"); +printParse("[]"); +printParse("[,,]"); +printParse("[4, 5, 5]"); diff --git a/nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED b/nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED new file mode 100644 index 00000000000..fcb31d54cd5 --- /dev/null +++ b/nashorn/test/script/basic/parser/primaryExpr.js.EXPECTED @@ -0,0 +1,199 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ThisExpression" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Identifier", + "name": "foo" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": null + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": true + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": 33 + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": 3.14 + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "BinaryExpression", + "operator": "*", + "left": { + "type": "BinaryExpression", + "operator": "+", + "left": { + "type": "Literal", + "value": 10 + }, + "right": { + "type": "Literal", + "value": 3 + } + }, + "right": { + "type": "Literal", + "value": 2 + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ObjectExpression", + "properties": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "x" + }, + "value": { + "type": "Literal", + "value": 3 + }, + "kind": "init" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [ + null, + null + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "ArrayExpression", + "elements": [ + { + "type": "Literal", + "value": 4 + }, + { + "type": "Literal", + "value": 5 + }, + { + "type": "Literal", + "value": 5 + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/returnStat.js b/nashorn/test/script/basic/parser/returnStat.js new file mode 100644 index 00000000000..741a23403c4 --- /dev/null +++ b/nashorn/test/script/basic/parser/returnStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check 'return' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("(function() { return })"); +printParse("(function() { return res })"); +printParse("(function() { return foo() })"); diff --git a/nashorn/test/script/basic/parser/returnStat.js.EXPECTED b/nashorn/test/script/basic/parser/returnStat.js.EXPECTED new file mode 100644 index 00000000000..149673c1d0f --- /dev/null +++ b/nashorn/test/script/basic/parser/returnStat.js.EXPECTED @@ -0,0 +1,88 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": null + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "Identifier", + "name": "res" + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "FunctionExpression", + "id": null, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ReturnStatement", + "argument": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "foo" + }, + "arguments": [] + } + } + ] + }, + "generator": false, + "expression": false + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/switchStat.js b/nashorn/test/script/basic/parser/switchStat.js new file mode 100644 index 00000000000..6f0dd75e741 --- /dev/null +++ b/nashorn/test/script/basic/parser/switchStat.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests for switch statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("switch (key) {}"); +printParse("switch (key) { case 2: hello(); break; }"); +printParse("switch (key) { case 4: hello(); break; case 2: world(); break; default: break }"); diff --git a/nashorn/test/script/basic/parser/switchStat.js.EXPECTED b/nashorn/test/script/basic/parser/switchStat.js.EXPECTED new file mode 100644 index 00000000000..6de4ba484b3 --- /dev/null +++ b/nashorn/test/script/basic/parser/switchStat.js.EXPECTED @@ -0,0 +1,123 @@ +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 2 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "hello" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "SwitchStatement", + "discriminant": { + "type": "Identifier", + "name": "key" + }, + "cases": [ + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 4 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "hello" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + }, + { + "type": "SwitchCase", + "test": { + "type": "Literal", + "value": 2 + }, + "consequent": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "world" + }, + "arguments": [] + } + }, + { + "type": "BreakStatement", + "label": null + } + ] + }, + { + "type": "SwitchCase", + "test": null, + "consequent": [ + { + "type": "BreakStatement", + "label": null + } + ] + } + ] + } + ] +} diff --git a/nashorn/test/script/basic/parser/throwStat.js b/nashorn/test/script/basic/parser/throwStat.js new file mode 100644 index 00000000000..345e3b8c7dc --- /dev/null +++ b/nashorn/test/script/basic/parser/throwStat.js @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests for throw statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("throw err"); +printParse("throw 'wrong'"); +printParse("throw new TypeError"); +printParse("throw new TypeError('not an array')"); +printParse("throw { msg: 'wrong!' }"); diff --git a/nashorn/test/script/basic/parser/throwStat.js.EXPECTED b/nashorn/test/script/basic/parser/throwStat.js.EXPECTED new file mode 100644 index 00000000000..d869cbda8df --- /dev/null +++ b/nashorn/test/script/basic/parser/throwStat.js.EXPECTED @@ -0,0 +1,85 @@ +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "Identifier", + "name": "err" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "Literal", + "value": "wrong" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "TypeError" + }, + "arguments": [] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "NewExpression", + "callee": { + "type": "Identifier", + "name": "TypeError" + }, + "arguments": [ + { + "type": "Literal", + "value": "not an array" + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ThrowStatement", + "argument": { + "type": "ObjectExpression", + "properties": [ + { + "key": { + "type": "Identifier", + "name": "msg" + }, + "value": { + "type": "Literal", + "value": "wrong!" + }, + "kind": "init" + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/tryCatchStat.js b/nashorn/test/script/basic/parser/tryCatchStat.js new file mode 100644 index 00000000000..de1531338b0 --- /dev/null +++ b/nashorn/test/script/basic/parser/tryCatchStat.js @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check try..catch statements. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("try { } catch (e) { }"); +printParse("try { } catch (e) { } finally {}"); +printParse("try { } finally {}"); +printParse("try { } catch (e) { handle() }"); +printParse("try { that() } catch (e) { handle() } finally { clean() }"); +printParse("try { that() } catch (e if e instanceof TypeError) { handle() } catch (e) { rest() }"); diff --git a/nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED b/nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED new file mode 100644 index 00000000000..16075e15420 --- /dev/null +++ b/nashorn/test/script/basic/parser/tryCatchStat.js.EXPECTED @@ -0,0 +1,305 @@ +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [] + } + }, + "finalizer": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [] + } + }, + "finalizer": { + "type": "BlockStatement", + "body": [] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": null, + "finalizer": { + "type": "BlockStatement", + "body": [] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": null + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "that" + }, + "arguments": [] + } + } + ] + }, + "guardedHandlers": [], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "clean" + }, + "arguments": [] + } + } + ] + } + } + ] + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "BlockStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "TryStatement", + "block": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "that" + }, + "arguments": [] + } + } + ] + }, + "guardedHandlers": [ + { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "guard": { + "type": "BinaryExpression", + "operator": "instanceof", + "left": { + "type": "Identifier", + "name": "e" + }, + "right": { + "type": "Identifier", + "name": "TypeError" + } + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "handle" + }, + "arguments": [] + } + } + ] + } + } + ], + "handler": { + "type": "CatchClause", + "param": { + "type": "Identifier", + "name": "e" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "CallExpression", + "callee": { + "type": "Identifier", + "name": "rest" + }, + "arguments": [] + } + } + ] + } + }, + "finalizer": null + } + ] + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/unaryExpr.js b/nashorn/test/script/basic/parser/unaryExpr.js new file mode 100644 index 00000000000..e21b55f32fa --- /dev/null +++ b/nashorn/test/script/basic/parser/unaryExpr.js @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check unary operators. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("x++"); +printParse("x--"); +printParse("delete x"); +printParse("void x"); +printParse("typeof x"); +printParse("++x"); +printParse("--x"); +printParse("+x"); +printParse("-x"); +printParse("~x"); +printParse("!x"); diff --git a/nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED b/nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED new file mode 100644 index 00000000000..d7a9532b677 --- /dev/null +++ b/nashorn/test/script/basic/parser/unaryExpr.js.EXPECTED @@ -0,0 +1,187 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "prefix": false, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "delete", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "void", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "typeof", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "++", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UpdateExpression", + "operator": "--", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "+", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "-", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "~", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "UnaryExpression", + "operator": "!", + "prefix": true, + "argument": { + "type": "Identifier", + "name": "x" + } + } + } + ] +} diff --git a/nashorn/test/script/basic/parser/useStrict.js b/nashorn/test/script/basic/parser/useStrict.js new file mode 100644 index 00000000000..4d1c7a94d09 --- /dev/null +++ b/nashorn/test/script/basic/parser/useStrict.js @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check if statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("'use strict'"); +printParse("function f() { 'use strict' }"); diff --git a/nashorn/test/script/basic/parser/useStrict.js.EXPECTED b/nashorn/test/script/basic/parser/useStrict.js.EXPECTED new file mode 100644 index 00000000000..870fbc24e04 --- /dev/null +++ b/nashorn/test/script/basic/parser/useStrict.js.EXPECTED @@ -0,0 +1,41 @@ +{ + "type": "Program", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "FunctionDeclaration", + "id": { + "type": "Identifier", + "name": "f" + }, + "params": [], + "defaults": [], + "rest": null, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "Literal", + "value": "use strict" + } + } + ] + }, + "generator": false, + "expression": false + } + ] +} diff --git a/nashorn/test/script/basic/parser/util.js b/nashorn/test/script/basic/parser/util.js new file mode 100644 index 00000000000..6170018b378 --- /dev/null +++ b/nashorn/test/script/basic/parser/util.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @subtest + */ + +// utilitity for parser tests + +load("nashorn:parser.js"); +function printParse(code) { + print(JSON.stringify(parse(code), null, ' ')); +} diff --git a/nashorn/test/script/basic/parser/varDecl.js b/nashorn/test/script/basic/parser/varDecl.js new file mode 100644 index 00000000000..e505761be8e --- /dev/null +++ b/nashorn/test/script/basic/parser/varDecl.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests to check variable declarations. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +// no initialization +printParse("var a"); +printParse("var a, b"); + +// init single, multiple +printParse("var a = 'hello'"); +printParse("var a = 1, b = 2, c = 3"); diff --git a/nashorn/test/script/basic/parser/varDecl.js.EXPECTED b/nashorn/test/script/basic/parser/varDecl.js.EXPECTED new file mode 100644 index 00000000000..96e71cf6f13 --- /dev/null +++ b/nashorn/test/script/basic/parser/varDecl.js.EXPECTED @@ -0,0 +1,123 @@ +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": null + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": null + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b" + }, + "init": null + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": { + "type": "Literal", + "value": "hello" + } + } + ] + } + ] +} +{ + "type": "Program", + "body": [ + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "a" + }, + "init": { + "type": "Literal", + "value": 1 + } + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "b" + }, + "init": { + "type": "Literal", + "value": 2 + } + } + ] + }, + { + "type": "VariableDeclaration", + "declarations": [ + { + "type": "VariableDeclarator", + "id": { + "type": "Identifier", + "name": "c" + }, + "init": { + "type": "Literal", + "value": 3 + } + } + ] + } + ] +} diff --git a/nashorn/test/script/basic/parser/withStat.js b/nashorn/test/script/basic/parser/withStat.js new file mode 100644 index 00000000000..3f94c7f596f --- /dev/null +++ b/nashorn/test/script/basic/parser/withStat.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * Tests for 'with' statement. + * + * @test + * @run + */ + +load(__DIR__ + "util.js"); + +printParse("with (scope) { x = y }"); diff --git a/nashorn/test/script/basic/parser/withStat.js.EXPECTED b/nashorn/test/script/basic/parser/withStat.js.EXPECTED new file mode 100644 index 00000000000..46bea479a26 --- /dev/null +++ b/nashorn/test/script/basic/parser/withStat.js.EXPECTED @@ -0,0 +1,32 @@ +{ + "type": "Program", + "body": [ + { + "type": "WithStatement", + "object": { + "type": "Identifier", + "name": "scope" + }, + "body": { + "type": "BlockStatement", + "body": [ + { + "type": "ExpressionStatement", + "expression": { + "type": "AssignmentExpression", + "operator": "=", + "left": { + "type": "Identifier", + "name": "x" + }, + "right": { + "type": "Identifier", + "name": "y" + } + } + } + ] + } + } + ] +} diff --git a/nashorn/test/src/META-INF/services/java.sql.Driver b/nashorn/test/src/META-INF/services/java.sql.Driver new file mode 100644 index 00000000000..295fe48075f --- /dev/null +++ b/nashorn/test/src/META-INF/services/java.sql.Driver @@ -0,0 +1 @@ +jdk.nashorn.api.NashornSQLDriver diff --git a/nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java b/nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java new file mode 100644 index 00000000000..2987b948548 --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/api/NashornSQLDriver.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api; + +import java.sql.*; +import java.util.Properties; +import java.util.logging.Logger; + +/** + * A dummy SQL driver for testing purpose. + */ +public final class NashornSQLDriver implements Driver { + static { + try { + DriverManager.registerDriver(new NashornSQLDriver(), null); + } catch (SQLException se) { + throw new RuntimeException(se); + } + } + + @Override + public boolean acceptsURL(String url) { + return url.startsWith("jdbc:nashorn:"); + } + + @Override + public Connection connect(String url, Properties info) { + throw new UnsupportedOperationException("I am a dummy!!"); + } + + @Override + public int getMajorVersion() { + return -1; + } + + @Override + public int getMinorVersion() { + return -1; + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { + return new DriverPropertyInfo[0]; + } + + @Override + public boolean jdbcCompliant() { + // no way! + return false; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java new file mode 100644 index 00000000000..acb57164029 --- /dev/null +++ b/nashorn/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting; + +import java.nio.IntBuffer; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Set; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.fail; +import org.testng.annotations.Test; + +/** + * Tests for pluggable external impls. of jdk.nashorn.api.scripting.JSObject. + * + * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external + * JSObject implementations. + */ +public class PluggableJSObjectTest { + public static class MapWrapperObject extends JSObject { + private final HashMap map = new LinkedHashMap<>(); + + public HashMap getMap() { + return map; + } + + @Override + public Object getMember(String name) { + return map.get(name); + } + + @Override + public void setMember(String name, Object value) { + map.put(name, value); + } + + @Override + public boolean hasMember(String name) { + return map.containsKey(name); + } + + @Override + public void removeMember(String name) { + map.remove(name); + } + + @Override + public Set keySet() { + return map.keySet(); + } + + @Override + public Collection values() { + return map.values(); + } + } + + @Test + // Named property access on a JSObject + public void namedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + e.put("obj", obj); + obj.getMap().put("foo", "bar"); + + // property-like access on MapWrapperObject objects + assertEquals(e.eval("obj.foo"), "bar"); + e.eval("obj.foo = 'hello'"); + assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); + assertEquals(e.eval("obj.foo"), "hello"); + assertEquals(obj.getMap().get("foo"), "hello"); + e.eval("delete obj.foo"); + assertFalse(obj.getMap().containsKey("foo")); + assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class BufferObject extends JSObject { + private final IntBuffer buf; + + public BufferObject(int size) { + buf = IntBuffer.allocate(size); + } + + public IntBuffer getBuffer() { + return buf; + } + + @Override + public Object getMember(String name) { + return name.equals("length")? buf.capacity() : null; + } + + @Override + public boolean hasSlot(int i) { + return i > -1 && i < buf.capacity(); + } + + @Override + public Object getSlot(int i) { + return buf.get(i); + } + + @Override + public void setSlot(int i, Object value) { + buf.put(i, ((Number)value).intValue()); + } + + @Override + public boolean isArray() { + return true; + } + } + + @Test + // array-like indexed access for a JSObject + public void indexedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final BufferObject buf = new BufferObject(2); + e.put("buf", buf); + + // array-like access on BufferObject objects + assertEquals(e.eval("buf.length"), buf.getBuffer().capacity()); + e.eval("buf[0] = 23"); + assertEquals(buf.getBuffer().get(0), 23); + assertEquals(e.eval("buf[0]"), 23); + assertEquals(e.eval("buf[1]"), 0); + buf.getBuffer().put(1, 42); + assertEquals(e.eval("buf[1]"), 42); + assertEquals(e.eval("Array.isArray(buf)"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Adder extends JSObject { + @Override + public Object call(Object thiz, Object... args) { + double res = 0.0; + for (Object arg : args) { + res += ((Number)arg).doubleValue(); + } + return res; + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a callable JSObject + public void callableJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("sum", new Adder()); + // check callability of Adder objects + assertEquals(e.eval("typeof sum"), "function"); + assertEquals(((Number)e.eval("sum(1, 2, 3, 4, 5)")).intValue(), 15); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Factory extends JSObject { + @Override + public Object newObject(Object... args) { + return new HashMap(); + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a factory JSObject + public void factoryJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("Factory", new Factory()); + + // check new on Factory + assertEquals(e.eval("typeof Factory"), "function"); + assertEquals(e.eval("typeof new Factory()"), "object"); + assertEquals(e.eval("(new Factory()) instanceof java.util.Map"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + // iteration tests + public void iteratingJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + obj.setMember("foo", "hello"); + obj.setMember("bar", "world"); + e.put("obj", obj); + + // check for..in + Object val = e.eval("var str = ''; for (i in obj) str += i; str"); + assertEquals(val.toString(), "foobar"); + + // check for..each..in + val = e.eval("var str = ''; for each (i in obj) str += i; str"); + assertEquals(val.toString(), "helloworld"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } +} diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java index 75f636ae6a0..c7b40c6367f 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java @@ -140,8 +140,8 @@ public class ScriptObjectMirrorTest { fail("obj[1] != 'world'"); } - if (!obj.call("func", new Object[0]).equals("hello")) { - fail("obj.call('func') != 'hello'"); + if (!obj.callMember("func", new Object[0]).equals("hello")) { + fail("obj.func() != 'hello'"); } // try setting properties @@ -210,8 +210,8 @@ public class ScriptObjectMirrorTest { e.eval("function func() {}"); e2.put("foo", e.get("func")); - final Object e2global = e2.eval("this"); - final Object newObj = ((ScriptObjectMirror) e2global).newObject("foo"); + final ScriptObjectMirror e2global = (ScriptObjectMirror)e2.eval("this"); + final Object newObj = ((ScriptObjectMirror)e2global.getMember("foo")).newObject(); assertTrue(newObj instanceof ScriptObjectMirror); } @@ -223,8 +223,8 @@ public class ScriptObjectMirrorTest { e.eval("function func() {}"); e2.put("func", e.get("func")); - final Object e2obj = e2.eval("({ foo: func })"); - final Object newObj = ((ScriptObjectMirror) e2obj).newObject("foo"); + final ScriptObjectMirror e2obj = (ScriptObjectMirror)e2.eval("({ foo: func })"); + final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject(); assertTrue(newObj instanceof ScriptObjectMirror); } } diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java index 16165ce704d..1b21c23f404 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java @@ -64,6 +64,7 @@ public class ContextTest { final Options options = new Options(""); final ErrorManager errors = new ErrorManager(); final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); + final boolean strict = cx.getEnv()._strict; final ScriptObject oldGlobal = Context.getGlobal(); Context.setGlobal(cx.createGlobal()); @@ -95,7 +96,7 @@ public class ContextTest { assertEquals(sobj.size(), 2); // add property - sobj.put("zee", "hello"); + sobj.put("zee", "hello", strict); assertEquals(sobj.get("zee"), "hello"); assertEquals(sobj.size(), 3);