aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraph <none@none>2014-09-04 12:43:13 -0400
committeraph <none@none>2014-09-04 12:43:13 -0400
commit3aaa28fdb53fb4ef7871d04bce38e7a9c9b67ef6 (patch)
tree006e4a8ecae9da6554b9d65ab07060da7b280387
parent59d2cf8b7db9dc6cbb1577bc91cf5e82b3a59c0f (diff)
parent2995ad09d817a24c0ac9eddfbde00ecb12a74c0a (diff)
-rw-r--r--.hgtags23
-rw-r--r--THIRD_PARTY_README18
-rw-r--r--make/build.xml79
-rw-r--r--make/nbproject/ide-file-targets.xml36
-rw-r--r--make/nbproject/project.xml22
-rw-r--r--make/project.properties8
-rw-r--r--samples/filebrowser.js100
-rw-r--r--samples/word_histogram.js53
-rw-r--r--src/jdk/nashorn/api/scripting/ScriptObjectMirror.java3
-rw-r--r--src/jdk/nashorn/api/scripting/package-info.java3
-rw-r--r--src/jdk/nashorn/internal/codegen/CodeGenerator.java4
-rw-r--r--src/jdk/nashorn/internal/ir/annotations/Reference.java2
-rw-r--r--src/jdk/nashorn/internal/objects/Global.java4
-rw-r--r--src/jdk/nashorn/internal/objects/NativeError.java14
-rw-r--r--src/jdk/nashorn/internal/objects/NativeObject.java39
-rw-r--r--src/jdk/nashorn/internal/objects/NativeRegExp.java6
-rw-r--r--src/jdk/nashorn/internal/runtime/CodeStore.java10
-rw-r--r--src/jdk/nashorn/internal/runtime/DebuggerSupport.java65
-rw-r--r--src/jdk/nashorn/internal/runtime/GlobalFunctions.java1
-rw-r--r--src/jdk/nashorn/internal/runtime/ScriptFunctionData.java4
-rw-r--r--src/jdk/nashorn/internal/runtime/ScriptObject.java61
-rw-r--r--src/jdk/nashorn/internal/runtime/Source.java32
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/Bootstrap.java14
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java19
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/NashornGuards.java15
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java6
-rw-r--r--src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java4
-rw-r--r--src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java68
-rw-r--r--src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java10
-rw-r--r--src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java79
-rw-r--r--src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java2
-rw-r--r--src/jdk/nashorn/internal/runtime/resources/Messages.properties1
-rw-r--r--test/script/basic/JDK-8030202.js57
-rw-r--r--test/script/basic/JDK-8030202.js.EXPECTED22
-rw-r--r--test/script/basic/JDK-8043930.js37
-rw-r--r--test/script/basic/JDK-8043930.js.EXPECTED1
-rw-r--r--test/script/basic/JDK-8044520.js145
-rw-r--r--test/script/basic/JDK-8044612.js37
-rw-r--r--test/script/basic/JDK-8044695.js37
-rw-r--r--test/script/basic/JDK-8044750.js53
-rw-r--r--test/script/nosecurity/JDK-8044798.js159
-rw-r--r--test/script/nosecurity/JDK-8044798.js.EXPECTED104
-rw-r--r--test/script/nosecurity/debuggersupportapi.js94
-rw-r--r--test/script/nosecurity/debuggersupportapi.js.EXPECTED22
-rw-r--r--test/script/nosecurity/nosecurity.js34
-rw-r--r--test/src/jdk/nashorn/api/scripting/ScopeTest.java17
-rw-r--r--test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java29
47 files changed, 1454 insertions, 199 deletions
diff --git a/.hgtags b/.hgtags
index 41dd2043..de6654db 100644
--- a/.hgtags
+++ b/.hgtags
@@ -266,6 +266,20 @@ f0b7b8b5e29a3a4e481fbeb9b346552c9819675e jdk8u5-b08
bc23b19e08eb1575663044902b6442ceaafa924f jdk8u5-b11
18b007062905dac9304605955a4b84eaf2a08553 jdk8u5-b12
e4fb85d69d6b33c9561b932ec5515f44c53c1017 jdk8u5-b13
+53cc5fda790e0f90dca53fb459c70517d76680bc jdk8u5-b31
+53cc5fda790e0f90dca53fb459c70517d76680bc jdk8u11-b01
+4dda2b1e51aa7977f53c261f983230fe505bbc3e jdk8u11-b02
+161f144c4e84037f655a2f6ebb0ba3057e8b18fa jdk8u11-b03
+2842beaa5db81731abe9d895181fbfceef720cf3 jdk8u11-b04
+7001e9f95b443a75e432205a29974c05b88e0fdc jdk8u11-b05
+daa414a4d8b712584d0818fab3fd31996e4cb645 jdk8u11-b06
+d9d482948b7c89161887b47e68e3367663d51b76 jdk8u11-b07
+a392513941025e2750acdcc45f9df2ec9080bde9 jdk8u11-b08
+dec6999877f39d3c17f7a092d8e2e17b676bb34b jdk8u11-b09
+d522ff5f53730cabd02c1863bb9d437c13bcc5e0 jdk8u11-b10
+3175dcbdd76ee9272276fa756247203dffb20596 jdk8u11-b11
+eea7f92c5fcc95310a6d946300ea47ac3e302cfe jdk8u11-b12
+b2c8eadc494bd32ed47d15d02cf942a8bd92c57f jdk8u11-b31
43a1183d2ab0ee3dbffd8bc47606e88dbe0c6116 jdk8u20-b02
9d69311869d513deecfebe767cc5f01502c9c01e jdk8u20-b03
e70dd55986e085185d976f2a78843a7d7eb87afd jdk8u20-b04
@@ -284,3 +298,12 @@ c720454d2435be052fd941a789ece9468d1e8f74 jdk8u20-b12
2f6add5fefb37cfeeb9a7745e7144f0b6d96bbea jdk8u20-b14
bb2d116675479fb2c9deaeeab6d4c41d41060693 jdk8u20-b15
c89a4945404ce80e26cb94c90fc13adad6b114bf jdk8u20-b16
+046bf6509a1f3fcf8c9c8b5d09beec0400f704d1 jdk8u20-b17
+847387339a561e50353c0805a54ec14eca256d2a jdk8u20-b18
+b047df215de40cb8a87ff1e2bac0b57bb9e2e121 jdk8u20-b19
+ed3439dca4a73a2dd4a284f3457f0af216a3eb55 jdk8u20-b20
+f2925491b61b22ac42f8c30ee9c6723ffa401a4c jdk8u20-b21
+5332595fe7ba2a1fc5564cc2689f378b04a56eb4 jdk8u20-b22
+ad36f9454ce38d78be39fc819902e1223765ee5e jdk8u20-b23
+f2925491b61b22ac42f8c30ee9c6723ffa401a4c jdk8u40-b00
+62468d841b842769d875bd97d10370585c296eb7 jdk8u40-b01
diff --git a/THIRD_PARTY_README b/THIRD_PARTY_README
index ce018105..6d1c60f2 100644
--- a/THIRD_PARTY_README
+++ b/THIRD_PARTY_README
@@ -2,7 +2,7 @@ DO NOT TRANSLATE OR LOCALIZE.
-----------------------------
%% This notice is provided with respect to ASM Bytecode Manipulation
-Framework v5.0, which may be included with JRE 8, and JDK 8, and
+Framework v5.0.3, which may be included with JRE 8, and JDK 8, and
OpenJDK 8.
--- begin of LICENSE ---
@@ -1471,7 +1471,7 @@ source code repository. It is licensed under Mozilla Public License (MPL),
version 2.0.
The NSS libraries are supplied in executable form, built from unmodified
-NSS source code labeled with the "NSS_3.13.1_RTM" release tag.
+NSS source code labeled with the "NSS_3_16_RTM" HG tag.
The NSS source code is available in the OpenJDK source code repository at:
jdk/test/sun/security/pkcs11/nss/src
@@ -3349,14 +3349,14 @@ info@urwpp.de or design@bigelowandholmes.com
-------------------------------------------------------------------------------
-%% This notice is provided with respect to zlib v1.2.5, which may be included
+%% This notice is provided with respect to zlib v1.2.8, which may be included
with JRE 8, JDK 8, and OpenJDK 8.
--- begin of LICENSE ---
- version 1.2.5, July 18th, 2005
+ version 1.2.8, April 28th, 2013
- Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
+ Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -3382,11 +3382,11 @@ with JRE 8, JDK 8, and OpenJDK 8.
-------------------------------------------------------------------------------
%% This notice is provided with respect to the following which may be
-included with JRE 8, JDK 8, and OpenJDK 8, except where noted:
+included with JRE 8, JDK 8, and OpenJDK 8.
- Apache Commons Math 2.2
- Apache Derby 10.10.1.2 [included with JDK 8]
- Apache Jakarta BCEL 5.2
+ Apache Commons Math 3.2
+ Apache Derby 10.10.1.3
+ Apache Jakarta BCEL 5.1
Apache Jakarta Regexp 1.4
Apache Santuario XML Security for Java 1.5.4
Apache Xalan-Java 2.7.1
diff --git a/make/build.xml b/make/build.xml
index 4d23f228..3b30a089 100644
--- a/make/build.xml
+++ b/make/build.xml
@@ -193,14 +193,16 @@
</jar>
</target>
- <target name="javadoc" depends="prepare">
- <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="src/overview.html" windowtitle="${nashorn.product.name} ${nashorn.version}" additionalparam="-quiet" failonerror="true">
+ <target name="javadoc" depends="jar">
+ <javadoc destdir="${dist.javadoc.dir}" use="yes" overview="src/overview.html"
+ extdirs="${nashorn.ext.path}" windowtitle="${nashorn.product.name} ${nashorn.version}"
+ additionalparam="-quiet" failonerror="true">
<classpath>
<pathelement location="${build.classes.dir}"/>
</classpath>
<fileset dir="${src.dir}" includes="**/*.java"/>
<fileset dir="${jdk.asm.src.dir}" includes="**/*.java"/>
- <link href="http://docs.oracle.com/javase/7/docs/api/"/>
+ <link href="http://docs.oracle.com/javase/8/docs/api/"/>
<!-- The following tags are used only in ASM sources - just ignore these -->
<tag name="label" description="label tag in ASM sources" enabled="false"/>
<tag name="linked" description="linked tag in ASM sources" enabled="false"/>
@@ -208,6 +210,19 @@
</javadoc>
</target>
+ <!-- generate javadoc only for nashorn extension api classes -->
+ <target name="javadocapi" depends="jar">
+ <javadoc destdir="${dist.javadoc.dir}" use="yes" extdirs="${nashorn.ext.path}"
+ windowtitle="${nashorn.product.name}" additionalparam="-quiet" failonerror="true">
+ <classpath>
+ <pathelement location="${build.classes.dir}"/>
+ </classpath>
+ <fileset dir="${src.dir}" includes="jdk/nashorn/api/**/*.java"/>
+ <link href="http://docs.oracle.com/javase/8/docs/api/"/>
+ </javadoc>
+ </target>
+
+
<!-- generate shell.html for shell tool documentation -->
<target name="shelldoc" depends="jar">
<java classname="${nashorn.shell.tool}" dir="${basedir}" output="${dist.dir}/shell.html" failonerror="true" fork="true">
@@ -336,22 +351,58 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" {
<echo message="WARNING: TestNG not available, will not run tests. Please copy testng.jar under test/lib directory."/>
</target>
- <target name="test" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
- <fileset id="test.classes" dir="${build.test.classes.dir}">
- <include name="**/api/javaaccess/*Test.class"/>
- <include name="**/api/scripting/*Test.class"/>
- <include name="**/codegen/*Test.class"/>
- <include name="**/parser/*Test.class"/>
- <include name="**/runtime/*Test.class"/>
- <include name="**/runtime/regexp/*Test.class"/>
- <include name="**/runtime/regexp/joni/*Test.class"/>
- <include name="**/framework/*Test.class"/>
+ <!-- only to be invoked as dependency of "test" target -->
+ <target name="-test-classes-all" depends="jar" unless="test.class">
+ <fileset id="test.classes" dir="${build.test.classes.dir}">
+ <include name="**/api/javaaccess/*Test.class"/>
+ <include name="**/api/scripting/*Test.class"/>
+ <include name="**/codegen/*Test.class"/>
+ <include name="**/parser/*Test.class"/>
+ <include name="**/runtime/*Test.class"/>
+ <include name="**/runtime/regexp/*Test.class"/>
+ <include name="**/runtime/regexp/joni/*Test.class"/>
+ <include name="**/framework/*Test.class"/>
+ </fileset>
+ </target>
+
+ <!-- only to be invoked as dependency of "test" target -->
+ <target name="-test-classes-single" depends="jar" if="test.class">
+ <fileset id="test.classes" dir="${build.test.classes.dir}">
+ <include name="${test.class}*"/>
+ </fileset>
+ </target>
+
+ <!-- only to be invoked as dependency of "test" target -->
+ <target name="-test-nosecurity" unless="test.class">
+ <fileset id="test.nosecurity.classes" dir="${build.test.classes.dir}">
+ <include name="**/framework/ScriptTest.class"/>
</fileset>
+ <testng outputdir="${build.nosecurity.test.results.dir}" classfilesetref="test.nosecurity.classes"
+ verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+ <jvmarg line="${ext.class.path}"/>
+ <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
+ <propertyset>
+ <propertyref prefix="nashorn."/>
+ </propertyset>
+ <propertyset>
+ <propertyref prefix="test-sys-prop-no-security."/>
+ <mapper from="test-sys-prop-no-security.*" to="*" type="glob"/>
+ </propertyset>
+ <classpath>
+ <pathelement path="${run.test.classpath}"/>
+ </classpath>
+ </testng>
+ </target>
+ <!-- only to be invoked as dependency of "test" target -->
+ <target name="-test-security">
+ <delete dir="${build.dir}/nashorn_code_cache"/>
+ <property name="debug.test.jvmargs" value=""/>
<testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
<jvmarg line="${ext.class.path}"/>
<jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}"/>
+ <jvmarg line="${debug.test.jvmargs}"/>
<propertyset>
<propertyref prefix="test-sys-prop."/>
<mapper from="test-sys-prop.*" to="*" type="glob"/>
@@ -363,6 +414,8 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" {
</testng>
</target>
+ <target name="test" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file, -test-security, -test-nosecurity" if="testng.available"/>
+
<target name="test-basicparallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file">
<!-- use just build.test.classes.dir to avoid referring to TestNG -->
<java classname="${parallel.test.runner}" dir="${basedir}" classpath="${build.test.classes.dir}" failonerror="true" fork="true">
diff --git a/make/nbproject/ide-file-targets.xml b/make/nbproject/ide-file-targets.xml
index cb017bb2..00a06351 100644
--- a/make/nbproject/ide-file-targets.xml
+++ b/make/nbproject/ide-file-targets.xml
@@ -22,38 +22,14 @@
questions.
-->
<project basedir=".." name="nashorn-IDE">
- <property file="nbproject/nbjdk.properties"/>
- <property location="${netbeans.user}/build.properties" name="user.properties.file"/>
- <property file="${user.properties.file}"/>
- <import file="jdk.xml"/>
- <import file="${basedir}/build-init.xml"/>
- <!-- TODO: edit the following target according to your needs -->
- <!-- (more info: http://www.netbeans.org/kb/articles/freeform-config.html#runsingle) -->
- <target depends="-jdk-init, init" name="debug-selected-file-in-src">
- <fail unless="debug.class">Must set property 'debug.class'</fail>
- <ant antfile="build.xml" inheritall="false" target="jar"/>
+ <target name="debug-selected-file-in-src">
+ <fail unless="test.class">Must set property 'debug.class'</fail>
<nbjpdastart addressproperty="jpda.address" name="nashorn" transport="dt_socket">
<classpath path="${run.test.classpath}"/>
</nbjpdastart>
- <java classname="${debug.class}" fork="false">
- <classpath path="${run.test.classpath}"/>
- <jvmarg line="${boot.class.path}"/>
- <jvmarg value="-Xdebug"/>
- <jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
- <jvmarg line="${run.test.jvmargs}"/>
- <arg value="${debug.class}"/>
- </java>
- </target>
- <!-- TODO: edit the following target according to your needs -->
- <!-- (more info: http://www.netbeans.org/kb/articles/freeform-config.html#runsingle) -->
- <target depends="-jdk-init, init" name="run-selected-file-in-src">
- <fail unless="run.class">Must set property 'run.class'</fail>
- <ant antfile="build.xml" inheritall="false" target="jar"/>
- <java classname="${run.class}" failonerror="true" fork="false">
- <classpath path="${run.test.classpath}"/>
- <jvmarg line="${boot.class.path}"/>
- <jvmarg line="${run.test.jvmargs}"/>
- <arg value="${run.class}"/>
- </java>
+ <ant antfile="build.xml" inheritall="false" target="test">
+ <property name="test.class" value="${test.class}"/>
+ <property name="debug.test.jvmargs" value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
+ </ant>
</target>
</project>
diff --git a/make/nbproject/project.xml b/make/nbproject/project.xml
index 828dc29d..2fcc6442 100644
--- a/make/nbproject/project.xml
+++ b/make/nbproject/project.xml
@@ -98,27 +98,27 @@
<script>nbproject/nbjdk.xml</script>
<target>debug-nb</target>
</action>
- <action name="debug.single">
- <script>nbproject/ide-file-targets.xml</script>
- <target>debug-selected-file-in-src</target>
+ <action name="run.single">
+ <script>build.xml</script>
+ <target>test</target>
<context>
- <property>debug.class</property>
- <folder>test/src</folder>
+ <property>test.class</property>
+ <folder>../test/src</folder>
<pattern>\.java$</pattern>
- <format>java-name</format>
+ <format>relative-path-noext</format>
<arity>
<one-file-only/>
</arity>
</context>
</action>
- <action name="run.single">
+ <action name="debug.single">
<script>nbproject/ide-file-targets.xml</script>
- <target>run-selected-file-in-src</target>
+ <target>debug-selected-file-in-src</target>
<context>
- <property>run.class</property>
- <folder>test/src</folder>
+ <property>test.class</property>
+ <folder>../test/src</folder>
<pattern>\.java$</pattern>
- <format>java-name</format>
+ <format>relative-path-noext</format>
<arity>
<one-file-only/>
</arity>
diff --git a/make/project.properties b/make/project.properties
index 8c5dd4f4..2abccdeb 100644
--- a/make/project.properties
+++ b/make/project.properties
@@ -59,6 +59,7 @@ nashorn.api.tests.jar=${build.dir}/nashorn-api-tests.jar
# test results directory
build.test.results.dir=${build.dir}/test/reports
+build.nosecurity.test.results.dir=${build.dir}/test/nosecurity/reports
# This directory is removed when the project is cleaned:
dist.dir=dist
@@ -110,6 +111,7 @@ run.classpath=\
# test scripts to run
test.dir=test
+test.nosecurity.dir=test/script/nosecurity
test.script.dir=test/script
test.basic.dir=test/script/basic
test.maptests.dir=test/script/maptests
@@ -127,8 +129,12 @@ test-sys-prop.test262.suite.dir=${test262.suite.dir}
test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases
test-sys-prop.test.basic.dir=${test.basic.dir}
+test-sys-prop-no-security.test.dir=${test.dir}
+test-sys-prop-no-security.test.js.roots=${test.nosecurity.dir}
+
# framework root for our script tests
test-sys-prop.test.js.framework=${test.script.dir}/assert.js
+test-sys-prop-no-security.test.js.framework=${test.script.dir}/assert.js
# Control the verbosity of ParserTest
test-sys-prop.parsertest.verbose=false
@@ -245,7 +251,7 @@ src.dir=src
test.src.dir=test/src
# -Xmx is used for all tests, -Xms only for octane benchmark
-run.test.xmx=3G
+run.test.xmx=2G
run.test.xms=2G
run.test.user.language=tr
diff --git a/samples/filebrowser.js b/samples/filebrowser.js
new file mode 100644
index 00000000..da00553a
--- /dev/null
+++ b/samples/filebrowser.js
@@ -0,0 +1,100 @@
+#// Usage: jjs -fx filebrowser.js -- <start_dir>
+
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// Uses -fx and javafx TreeView to visualize directories
+if (!$OPTIONS._fx) {
+ print("Usage: jjs -fx filebrowser.js -- <start_dir>");
+ exit(1);
+}
+
+// Java classes used
+var File = Java.type("java.io.File");
+var Files = Java.type("java.nio.file.Files");
+
+// check directory argument, if passed
+var dir = arguments.length > 0? new File(arguments[0]) : new File(".");
+if (! dir.isDirectory()) {
+ print(dir + " is not a directory!");
+ exit(2);
+}
+
+// JavaFX classes used
+var FXCollections = Java.type("javafx.collections.FXCollections");
+var Scene = Java.type("javafx.scene.Scene");
+var TreeItem = Java.type("javafx.scene.control.TreeItem");
+var TreeView = Java.type("javafx.scene.control.TreeView");
+
+// create a subclass of JavaFX TreeItem class
+var LazyTreeItem = Java.extend(TreeItem);
+
+// lazily filling children of a directory LazyTreeItem
+function buildChildren(dir) {
+ var children = FXCollections.observableArrayList();
+ var stream = Files.list(dir.toPath());
+ stream.forEach(function(path) {
+ var file = path.toFile();
+ var item = file.isDirectory()?
+ makeLazyTreeItem(file) : new TreeItem(file.name);
+ children.add(item);
+ });
+ stream.close();
+ return children;
+}
+
+// create an instance LazyTreeItem with override methods
+function makeLazyTreeItem(dir) {
+ var item = new LazyTreeItem(dir.name) {
+ expanded: false,
+ isLeaf: function() false,
+ getChildren: function() {
+ if (! this.expanded) {
+ // call super class (TreeItem) method
+ Java.super(item).getChildren().setAll(buildChildren(dir));
+ this.expanded = true;
+ }
+ // call super class (TreeItem) method
+ return Java.super(item).getChildren();
+ }
+ }
+ return item;
+}
+
+// JavaFX start method
+function start(stage) {
+ stage.title = dir.absolutePath;
+ var rootItem = makeLazyTreeItem(dir);
+ rootItem.expanded = true;
+ var tree = new TreeView(rootItem);
+ stage.scene = new Scene(tree, 300, 450);
+ stage.show();
+}
diff --git a/samples/word_histogram.js b/samples/word_histogram.js
new file mode 100644
index 00000000..9c739ea0
--- /dev/null
+++ b/samples/word_histogram.js
@@ -0,0 +1,53 @@
+#nashorn word histogram of a file
+
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of Oracle nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This example demonstrates how to print word histogram
+ * of a given text file using regex, array and JSON
+ * functions.
+ */
+
+if (arguments.length < 1) {
+ print("Usage: jjs -scripting word_histogram.js -- <file>");
+ exit(1);
+}
+
+var obj = {};
+
+readFully(arguments[0]).
+ split(/[^\w+]/).
+ forEach(function(x)
+ (x in obj? obj[x]++ : obj[x] = 1));
+
+print(JSON.stringify(obj));
+
diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index b1255336..b8035d2e 100644
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -496,7 +496,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
public void setProto(final Object proto) {
inGlobal(new Callable<Void>() {
@Override public Void call() {
- sobj.setProtoCheck(unwrap(proto, global));
+ sobj.setPrototypeOf(unwrap(proto, global));
return null;
}
});
@@ -621,6 +621,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
/**
* Utilitity to convert this script object to the given type.
*
+ * @param <T> destination type to convert to
* @param type destination type to convert to
* @return converted object
*/
diff --git a/src/jdk/nashorn/api/scripting/package-info.java b/src/jdk/nashorn/api/scripting/package-info.java
index 6876151e..f017ba9e 100644
--- a/src/jdk/nashorn/api/scripting/package-info.java
+++ b/src/jdk/nashorn/api/scripting/package-info.java
@@ -32,7 +32,8 @@
* ScriptEngine nashornEngine = new ScriptEngineManager().getEngineByName("Nashorn");
* </pre>
* <p>Nashorn script engines implement the optional {@link javax.script.Invocable} and {@link javax.script.Compilable}
- * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. See
+ * interfaces, allowing for efficient pre-compilation and repeated execution of scripts. In addition,
+ * this package provides nashorn specific extension classes, interfaces and methods. See
* {@link jdk.nashorn.api.scripting.NashornScriptEngineFactory} for further details.
*/
package jdk.nashorn.api.scripting;
diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java
index 882846c6..52bdc7cb 100644
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -1500,7 +1500,9 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
method.dup();
if (protoNode != null) {
load(protoNode);
- method.invoke(ScriptObject.SET_PROTO_CHECK);
+ // take care of { __proto__: 34 } or some such!
+ method.convert(Type.OBJECT);
+ method.invoke(ScriptObject.SET_PROTO_FROM_LITERAL);
} else {
globalObjectPrototype();
method.invoke(ScriptObject.SET_PROTO);
diff --git a/src/jdk/nashorn/internal/ir/annotations/Reference.java b/src/jdk/nashorn/internal/ir/annotations/Reference.java
index 20c8ffca..27f6a697 100644
--- a/src/jdk/nashorn/internal/ir/annotations/Reference.java
+++ b/src/jdk/nashorn/internal/ir/annotations/Reference.java
@@ -32,9 +32,7 @@ import java.lang.annotation.RetentionPolicy;
* Reference node in AST, i.e. anything not a copy. Important for
* AST traversal and cloning. Cloning currently as a rule uses
* existingOrSame for references and otherwise existingOrCopy
- * <p>
*/
-
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Reference {
// EMPTY
diff --git a/src/jdk/nashorn/internal/objects/Global.java b/src/jdk/nashorn/internal/objects/Global.java
index 00019382..0614c4b4 100644
--- a/src/jdk/nashorn/internal/objects/Global.java
+++ b/src/jdk/nashorn/internal/objects/Global.java
@@ -1908,8 +1908,8 @@ public final class Global extends ScriptObject implements Scope {
// ES6 draft compliant __proto__ property of Object.prototype
// accessors on Object.prototype for "__proto__"
- final ScriptFunction getProto = ScriptFunctionImpl.makeFunction("getProto", ScriptObject.GETPROTO);
- final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", ScriptObject.SETPROTOCHECK);
+ final ScriptFunction getProto = ScriptFunctionImpl.makeFunction("getProto", NativeObject.GET__PROTO__);
+ final ScriptFunction setProto = ScriptFunctionImpl.makeFunction("setProto", NativeObject.SET__PROTO__);
ObjectPrototype.addOwnProperty("__proto__", Attribute.NOT_ENUMERABLE, getProto, setProto);
diff --git a/src/jdk/nashorn/internal/objects/NativeError.java b/src/jdk/nashorn/internal/objects/NativeError.java
index 1b6b8094..18aa11e5 100644
--- a/src/jdk/nashorn/internal/objects/NativeError.java
+++ b/src/jdk/nashorn/internal/objects/NativeError.java
@@ -327,7 +327,12 @@ public final class NativeError extends ScriptObject {
final Object exception = ECMAException.getException(sobj);
if (exception instanceof Throwable) {
Object value = getScriptStackString(sobj, (Throwable)exception);
- sobj.put(STACK, value, false);
+ if (sobj.hasOwnProperty(STACK)) {
+ sobj.put(STACK, value, false);
+ } else {
+ sobj.addOwnProperty(STACK, Attribute.NOT_ENUMERABLE, value);
+ }
+
return value;
}
@@ -346,7 +351,12 @@ public final class NativeError extends ScriptObject {
public static Object setStack(final Object self, final Object value) {
Global.checkObject(self);
final ScriptObject sobj = (ScriptObject)self;
- sobj.set(STACK, value, false);
+ if (sobj.hasOwnProperty(STACK)) {
+ sobj.put(STACK, value, false);
+ } else {
+ sobj.addOwnProperty(STACK, Attribute.NOT_ENUMERABLE, value);
+ }
+
return value;
}
diff --git a/src/jdk/nashorn/internal/objects/NativeObject.java b/src/jdk/nashorn/internal/objects/NativeObject.java
index 9cde4faf..4fd8aeb5 100644
--- a/src/jdk/nashorn/internal/objects/NativeObject.java
+++ b/src/jdk/nashorn/internal/objects/NativeObject.java
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.objects;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
@@ -74,6 +75,9 @@ import jdk.nashorn.internal.runtime.linker.NashornBeansLinker;
*/
@ScriptClass("Object")
public final class NativeObject {
+ public static final MethodHandle GET__PROTO__ = findOwnMH("get__proto__", ScriptObject.class, Object.class);
+ public static final MethodHandle SET__PROTO__ = findOwnMH("set__proto__", Object.class, Object.class, Object.class);
+
private static final Object TO_STRING = new Object();
private static InvokeByName getTO_STRING() {
@@ -86,6 +90,35 @@ public final class NativeObject {
});
}
+ @SuppressWarnings("unused")
+ private static ScriptObject get__proto__(final Object self) {
+ // See ES6 draft spec: B.2.2.1.1 get Object.prototype.__proto__
+ // Step 1 Let O be the result of calling ToObject passing the this.
+ final Object obj = Global.toObject(self);
+ Global.checkObject(obj);
+ final ScriptObject sobj = (ScriptObject)obj;
+ return sobj.getProto();
+ }
+
+ @SuppressWarnings("unused")
+ private static Object set__proto__(final Object self, final Object proto) {
+ // See ES6 draft spec: B.2.2.1.2 set Object.prototype.__proto__
+ // Step 1
+ Global.checkObjectCoercible(self);
+ // Step 4
+ if (! (self instanceof ScriptObject)) {
+ return UNDEFINED;
+ }
+
+ final ScriptObject sobj = (ScriptObject)self;
+ // __proto__ assignment ignores non-nulls and non-objects
+ // step 3: If Type(proto) is neither Object nor Null, then return undefined.
+ if (proto == null || proto instanceof ScriptObject) {
+ sobj.setPrototypeOf(proto);
+ }
+ return UNDEFINED;
+ }
+
private static final MethodType MIRROR_GETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class);
private static final MethodType MIRROR_SETTER_TYPE = MethodType.methodType(Object.class, ScriptObjectMirror.class, Object.class);
@@ -160,7 +193,7 @@ public final class NativeObject {
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object setPrototypeOf(final Object self, final Object obj, final Object proto) {
if (obj instanceof ScriptObject) {
- ((ScriptObject)obj).setProtoCheck(proto);
+ ((ScriptObject)obj).setPrototypeOf(proto);
return obj;
} else if (obj instanceof ScriptObjectMirror) {
((ScriptObjectMirror)obj).setProto(proto);
@@ -777,4 +810,8 @@ public final class NativeObject {
return new LinkRequestImpl(CallSiteDescriptorFactory.create(MethodHandles.publicLookup(), operation,
methodType), false, source);
}
+
+ private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
+ return MH.findStatic(MethodHandles.lookup(), NativeObject.class, name, MH.type(rtype, types));
+ }
}
diff --git a/src/jdk/nashorn/internal/objects/NativeRegExp.java b/src/jdk/nashorn/internal/objects/NativeRegExp.java
index 89a9a828..34657d25 100644
--- a/src/jdk/nashorn/internal/objects/NativeRegExp.java
+++ b/src/jdk/nashorn/internal/objects/NativeRegExp.java
@@ -731,6 +731,12 @@ public final class NativeRegExp extends ScriptObject {
if (nextChar == '$') {
// Skip past $
cursor++;
+ if (cursor == replacement.length()) {
+ // nothing after "$"
+ sb.append('$');
+ break;
+ }
+
nextChar = replacement.charAt(cursor);
final int firstDigit = nextChar - '0';
diff --git a/src/jdk/nashorn/internal/runtime/CodeStore.java b/src/jdk/nashorn/internal/runtime/CodeStore.java
index 8f595999..85a74ccb 100644
--- a/src/jdk/nashorn/internal/runtime/CodeStore.java
+++ b/src/jdk/nashorn/internal/runtime/CodeStore.java
@@ -37,7 +37,6 @@ import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
-import java.util.Base64;
import java.util.Map;
/**
@@ -48,9 +47,6 @@ final class CodeStore {
private final File dir;
private final int minSize;
- // Message digest to file name encoder
- private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding();
-
// Default minimum size for storing a compiled script class
private final static int DEFAULT_MIN_SIZE = 1000;
@@ -108,8 +104,7 @@ final class CodeStore {
return null;
}
- final String digest = BASE64.encodeToString(source.getDigest());
- final File file = new File(dir, digest);
+ final File file = new File(dir, source.getDigest());
try {
return AccessController.doPrivileged(new PrivilegedExceptionAction<CompiledScript>() {
@@ -157,8 +152,7 @@ final class CodeStore {
}
}
- final String digest = BASE64.encodeToString(source.getDigest());
- final File file = new File(dir, digest);
+ final File file = new File(dir, source.getDigest());
final CompiledScript script = new CompiledScript(source, mainClassName, classBytes, constants);
try {
diff --git a/src/jdk/nashorn/internal/runtime/DebuggerSupport.java b/src/jdk/nashorn/internal/runtime/DebuggerSupport.java
index 261bc020..38e5d858 100644
--- a/src/jdk/nashorn/internal/runtime/DebuggerSupport.java
+++ b/src/jdk/nashorn/internal/runtime/DebuggerSupport.java
@@ -25,12 +25,20 @@
package jdk.nashorn.internal.runtime;
+import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.reflect.Field;
+import java.net.URL;
import java.util.HashSet;
import java.util.Set;
+import jdk.nashorn.internal.scripts.JS;
/**
* This class provides support for external debuggers. Its primary purpose is
* is to simplify the debugger tasks and provide better performance.
+ * Even though the methods are not public, there are still part of the
+ * external debugger interface.
*/
final class DebuggerSupport {
/**
@@ -46,6 +54,11 @@ final class DebuggerSupport {
*/
@SuppressWarnings("unused")
DebuggerValueDesc forceLoad = new DebuggerValueDesc(null, false, null, null);
+
+ // Hook to force the loading of the SourceInfo class
+ @SuppressWarnings("unused")
+ final
+ SourceInfo srcInfo = new SourceInfo(null, 0, null, null);
}
/** This class is used to send a bulk description of a value. */
@@ -70,6 +83,54 @@ final class DebuggerSupport {
}
}
+ static class SourceInfo {
+ final String name;
+ final URL url;
+ final int hash;
+ final char[] content;
+
+ SourceInfo(final String name, final int hash, final URL url, final char[] content) {
+ this.name = name;
+ this.hash = hash;
+ this.url = url;
+ this.content = content;
+ }
+ }
+
+ /**
+ * Hook that is called just before invoking method handle
+ * from ScriptFunctionData via invoke, constructor method calls.
+ *
+ * @param mh script class method about to be invoked.
+ */
+ static void notifyInvoke(final MethodHandle mh) {
+ // Do nothing here. This is placeholder method on which a
+ // debugger can place a breakpoint so that it can access the
+ // (script class) method handle that is about to be invoked.
+ // See ScriptFunctionData.invoke and ScriptFunctionData.construct.
+ }
+
+ /**
+ * Return the script source info for the given script class.
+ *
+ * @param clazz compiled script class
+ * @return SourceInfo
+ */
+ static SourceInfo getSourceInfo(final Class<?> clazz) {
+ if (JS.class.isAssignableFrom(clazz)) {
+ try {
+ final Field sourceField = clazz.getDeclaredField(SOURCE.symbolName());
+ sourceField.setAccessible(true);
+ final Source src = (Source) sourceField.get(null);
+ return src.getSourceInfo();
+ } catch (final IllegalAccessException | NoSuchFieldException ignored) {
+ return null;
+ }
+ }
+
+ return null;
+ }
+
/**
* Return the current context global.
* @return context global.
@@ -84,7 +145,7 @@ final class DebuggerSupport {
* @param self Receiver to use.
* @param string String to evaluate.
* @param returnException true if exceptions are to be returned.
- * @return Result of eval as string, or, an exception or null depending on returnException.
+ * @return Result of eval, or, an exception or null depending on returnException.
*/
static Object eval(final ScriptObject scope, final Object self, final String string, final boolean returnException) {
final ScriptObject global = Context.getGlobal();
@@ -235,7 +296,7 @@ final class DebuggerSupport {
* @param value Arbitrary value to be displayed by the debugger.
* @return A string representation of the value or an array of DebuggerValueDesc.
*/
- private static String valueAsString(final Object value) {
+ static String valueAsString(final Object value) {
final JSType type = JSType.of(value);
switch (type) {
diff --git a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
index c750d80e..10747a1b 100644
--- a/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
+++ b/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
@@ -459,5 +459,4 @@ loop:
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
return MH.findStatic(MethodHandles.lookup(), GlobalFunctions.class, name, MH.type(rtype, types));
}
-
}
diff --git a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
index ad40d622..001996b7 100644
--- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
+++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
@@ -519,6 +519,8 @@ public abstract class ScriptFunctionData implements Serializable {
final Object selfObj = convertThisObject(self);
final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
+ DebuggerSupport.notifyInvoke(mh);
+
if (isVarArg(mh)) {
if (needsCallee(mh)) {
return mh.invokeExact(fn, selfObj, args);
@@ -572,6 +574,8 @@ public abstract class ScriptFunctionData implements Serializable {
final MethodHandle mh = getGenericConstructor();
final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments;
+ DebuggerSupport.notifyInvoke(mh);
+
if (isVarArg(mh)) {
if (needsCallee(mh)) {
return mh.invokeExact(fn, args);
diff --git a/src/jdk/nashorn/internal/runtime/ScriptObject.java b/src/jdk/nashorn/internal/runtime/ScriptObject.java
index d4556d89..deae803e 100644
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -132,9 +132,7 @@ public abstract class ScriptObject implements PropertyAccess {
/** Method handle to retrive prototype of this object */
public static final MethodHandle GETPROTO = findOwnMH("getProto", ScriptObject.class);
- /** Method handle to set prototype of this object */
- public static final MethodHandle SETPROTOCHECK = findOwnMH("setProtoCheck", void.class, Object.class);
- static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class, boolean.class);
+ static final MethodHandle MEGAMORPHIC_GET = findOwnMH("megamorphicGet", Object.class, String.class, boolean.class);
static final MethodHandle GLOBALFILTER = findOwnMH("globalFilter", Object.class, Object.class);
static final MethodHandle SETFIELD = findOwnMH("setField", void.class, CallSiteDescriptor.class, PropertyMap.class, PropertyMap.class, MethodHandle.class, Object.class, Object.class);
@@ -160,7 +158,7 @@ public abstract class ScriptObject implements PropertyAccess {
public static final Call SET_PROTO = virtualCallNoLookup(ScriptObject.class, "setInitialProto", 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);
+ public static final Call SET_PROTO_FROM_LITERAL = virtualCallNoLookup(ScriptObject.class, "setProtoFromLiteral", 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);
@@ -1127,14 +1125,21 @@ public abstract class ScriptObject implements PropertyAccess {
/**
* Set the __proto__ of an object with checks.
+ * This is the built-in operation [[SetPrototypeOf]]
+ * See ES6 draft spec: 9.1.2 [[SetPrototypeOf]] (V)
+ *
* @param newProto Prototype to set.
*/
- public final void setProtoCheck(final Object newProto) {
- if (!isExtensible()) {
- throw typeError("__proto__.set.non.extensible", ScriptRuntime.safeToString(this));
- }
-
+ public final void setPrototypeOf(final Object newProto) {
if (newProto == null || newProto instanceof ScriptObject) {
+ if (!isExtensible()) {
+ // okay to set same proto again - even if non-extensible
+ if (newProto == getProto()) {
+ return;
+ }
+ throw typeError("__proto__.set.non.extensible", ScriptRuntime.safeToString(this));
+ }
+
// check for circularity
ScriptObject p = (ScriptObject)newProto;
while (p != null) {
@@ -1145,14 +1150,27 @@ public abstract class ScriptObject implements PropertyAccess {
}
setProto((ScriptObject)newProto);
} else {
- final Global global = Context.getGlobal();
- final Object newProtoObject = JSType.toScriptObject(global, newProto);
+ throw typeError("cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto));
+ }
+ }
- if (newProtoObject instanceof ScriptObject) {
- setProto((ScriptObject)newProtoObject);
- } else {
- throw typeError(global, "cant.set.proto.to.non.object", ScriptRuntime.safeToString(this), ScriptRuntime.safeToString(newProto));
- }
+ /**
+ * Set the __proto__ of an object from an object literal.
+ * See ES6 draft spec: B.3.1 __proto__ Property Names in
+ * Object Initializers. Step 6 handling of "__proto__".
+ *
+ * @param newProto Prototype to set.
+ */
+ public final void setProtoFromLiteral(final Object newProto) {
+ if (newProto == null || newProto instanceof ScriptObject) {
+ setPrototypeOf(newProto);
+ } else {
+ // Some non-object, non-null. Then, we need to set
+ // Object.prototype as the new __proto__
+ //
+ // var obj = { __proto__ : 34 };
+ // print(obj.__proto__ === Object.prototype); // => true
+ setPrototypeOf(Global.objectPrototype());
}
}
@@ -1727,7 +1745,7 @@ public abstract class ScriptObject implements PropertyAccess {
protected GuardedInvocation findGetMethod(final CallSiteDescriptor desc, final LinkRequest request, final String operator) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
if (request.isCallSiteUnstable() || hasWithScope()) {
- return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator), isScope() && NashornCallSiteDescriptor.isScope(desc));
+ return findMegaMorphicGetMethod(desc, name, "getMethod".equals(operator));
}
final FindProperty find = findProperty(name, true);
@@ -1770,22 +1788,19 @@ public abstract class ScriptObject implements PropertyAccess {
}
private static GuardedInvocation findMegaMorphicGetMethod(final CallSiteDescriptor desc, final String name,
- final boolean isMethod, final boolean isScope) {
- final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod, isScope);
+ final boolean isMethod) {
+ final MethodHandle invoker = MH.insertArguments(MEGAMORPHIC_GET, 1, name, isMethod);
final MethodHandle guard = getScriptObjectGuard(desc.getMethodType());
return new GuardedInvocation(invoker, guard);
}
@SuppressWarnings("unused")
- private Object megamorphicGet(final String key, final boolean isMethod, final boolean isScope) {
+ private Object megamorphicGet(final String key, final boolean isMethod) {
final FindProperty find = findProperty(key, true);
if (find != null) {
return find.getObjectValue();
}
- if (isScope) {
- throw referenceError("not.defined", key);
- }
return isMethod ? getNoSuchMethod(key) : invokeNoSuchProperty(key);
}
diff --git a/src/jdk/nashorn/internal/runtime/Source.java b/src/jdk/nashorn/internal/runtime/Source.java
index f7e890ff..4f9c16e6 100644
--- a/src/jdk/nashorn/internal/runtime/Source.java
+++ b/src/jdk/nashorn/internal/runtime/Source.java
@@ -45,6 +45,7 @@ import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
+import java.util.Base64;
import java.util.Objects;
import java.util.WeakHashMap;
import jdk.nashorn.api.scripting.URLReader;
@@ -59,6 +60,9 @@ public final class Source {
private static final int BUF_SIZE = 8 * 1024;
private static final Cache CACHE = new Cache();
+ // Message digest to file name encoder
+ private final static Base64.Encoder BASE64 = Base64.getUrlEncoder().withoutPadding();
+
/**
* Descriptive name of the source as supplied by the user. Used for error
* reporting to the user. For example, SyntaxError will use this to print message.
@@ -79,8 +83,8 @@ public final class Source {
/** Cached hash code */
private int hash;
- /** Message digest */
- private byte[] digest;
+ /** Base64-encoded SHA1 digest of this source object */
+ private volatile byte[] digest;
// Do *not* make this public, ever! Trusts the URL and content.
private Source(final String name, final String base, final Data data) {
@@ -124,6 +128,11 @@ public final class Source {
}
}
+ /* package-private */
+ DebuggerSupport.SourceInfo getSourceInfo() {
+ return new DebuggerSupport.SourceInfo(getName(), data.hashCode(), data.url(), data.array());
+ }
+
// Wrapper to manage lazy loading
private static interface Data {
@@ -706,12 +715,17 @@ public final class Source {
}
/**
- * Get a message digest for this source.
+ * Get a Base64-encoded SHA1 digest for this source.
*
- * @return a message digest for this source
+ * @return a Base64-encoded SHA1 digest for this source
*/
- public synchronized byte[] getDigest() {
- if (digest == null) {
+ public String getDigest() {
+ return new String(getDigestBytes(), StandardCharsets.US_ASCII);
+ }
+
+ private byte[] getDigestBytes() {
+ byte[] ldigest = digest;
+ if (ldigest == null) {
final char[] content = data();
final byte[] bytes = new byte[content.length * 2];
@@ -731,12 +745,12 @@ public final class Source {
if (getURL() != null) {
md.update(getURL().toString().getBytes(StandardCharsets.UTF_8));
}
- digest = md.digest(bytes);
- } catch (NoSuchAlgorithmException e) {
+ digest = ldigest = BASE64.encode(md.digest(bytes));
+ } catch (final NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
- return digest;
+ return ldigest;
}
/**
diff --git a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
index c8f39fcf..48821036 100644
--- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
+++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
@@ -61,9 +61,17 @@ public final class Bootstrap {
private static final DynamicLinker dynamicLinker;
static {
final DynamicLinkerFactory factory = new DynamicLinkerFactory();
- factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(),
- new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker());
- factory.setFallbackLinkers(new NashornBeansLinker(), new NashornBottomLinker());
+ final NashornBeansLinker nashornBeansLinker = new NashornBeansLinker();
+ final JSObjectLinker jsObjectLinker = new JSObjectLinker(nashornBeansLinker);
+ factory.setPrioritizedLinkers(
+ new NashornLinker(),
+ new NashornPrimitiveLinker(),
+ new NashornStaticClassLinker(),
+ new BoundDynamicMethodLinker(),
+ new JavaSuperAdapterLinker(),
+ jsObjectLinker,
+ new ReflectionCheckLinker());
+ factory.setFallbackLinkers(nashornBeansLinker, new NashornBottomLinker());
factory.setSyncOnRelink(true);
final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
if (relinkThreshold > -1) {
diff --git a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
index f3c8284b..52fb46bc 100644
--- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
@@ -30,6 +30,7 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.util.HashMap;
import java.util.Map;
+import javax.script.Bindings;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.GuardedTypeConversion;
@@ -48,14 +49,23 @@ import jdk.nashorn.internal.runtime.JSType;
* as ScriptObjects from other Nashorn contexts.
*/
final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTypeConverterFactory {
+ private final NashornBeansLinker nashornBeansLinker;
+
+ JSObjectLinker(final NashornBeansLinker nashornBeansLinker) {
+ this.nashornBeansLinker = nashornBeansLinker;
+ }
+
@Override
public boolean canLinkType(final Class<?> type) {
return canLinkTypeStatic(type);
}
static boolean canLinkTypeStatic(final Class<?> type) {
- // can link JSObject
- return JSObject.class.isAssignableFrom(type);
+ // can link JSObject also handles Map, Bindings to make
+ // sure those are not JSObjects.
+ return Map.class.isAssignableFrom(type) ||
+ Bindings.class.isAssignableFrom(type) ||
+ JSObject.class.isAssignableFrom(type);
}
@Override
@@ -72,6 +82,11 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker, GuardingTy
final GuardedInvocation inv;
if (self instanceof JSObject) {
inv = lookup(desc);
+ } else if (self instanceof Map || self instanceof Bindings) {
+ // guard to make sure the Map or Bindings does not turn into JSObject later!
+ final GuardedInvocation beanInv = nashornBeansLinker.getGuardedInvocation(request, linkerServices);
+ inv = new GuardedInvocation(beanInv.getInvocation(),
+ NashornGuards.combineGuards(beanInv.getGuard(), NashornGuards.getNotJSObjectGuard()));
} else {
throw new AssertionError(); // Should never reach here.
}
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java b/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
index ca3e10c4..77c5e93c 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
@@ -31,6 +31,7 @@ import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.ref.WeakReference;
import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Property;
@@ -43,6 +44,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
*/
public final class NashornGuards {
private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class);
+ private static final MethodHandle IS_NOT_JSOBJECT = findOwnMH("isNotJSObject", boolean.class, Object.class);
private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
private static final MethodHandle SAME_OBJECT = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
@@ -61,6 +63,14 @@ public final class NashornGuards {
}
/**
+ * Get the guard that checks if an item is not a {@code JSObject}
+ * @return method handle for guard
+ */
+ public static MethodHandle getNotJSObjectGuard() {
+ return IS_NOT_JSOBJECT;
+ }
+
+ /**
* Get the guard that checks if an item is a {@code ScriptFunction}
* @return method handle for guard
*/
@@ -157,6 +167,11 @@ public final class NashornGuards {
}
@SuppressWarnings("unused")
+ private static boolean isNotJSObject(final Object self) {
+ return !(self instanceof JSObject);
+ }
+
+ @SuppressWarnings("unused")
private static boolean isScriptFunction(final Object self) {
return self instanceof ScriptFunction;
}
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
index 272b4ec0..f8ea9916 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.runtime.linker;
+import java.lang.reflect.Modifier;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.beans.StaticClass;
@@ -65,10 +66,15 @@ final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
return null;
}
final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();
+
Bootstrap.checkReflectionAccess(receiverClass, true);
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
// We intercept "new" on StaticClass instances to provide additional capabilities
if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) {
+ if (! Modifier.isPublic(receiverClass.getModifiers())) {
+ throw ECMAErrors.typeError("new.on.nonpublic.javatype", receiverClass.getName());
+ }
+
// make sure new is on accessible Class
Context.checkPackageAccess(receiverClass);
diff --git a/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java b/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
index a75e84ca..eb612cd3 100644
--- a/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
+++ b/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
@@ -771,7 +771,7 @@ final class Analyser extends Parser {
while (value < end) {
int ovalue = value;
- buf = Character.toLowerCase(chars[value++]);
+ buf = EncodingHelper.toLowerCase(chars[value++]);
if (chars[ovalue] != buf) {
@@ -779,7 +779,7 @@ final class Analyser extends Parser {
System.arraycopy(chars, sn.p, sbuf, 0, ovalue - sn.p);
value = ovalue;
while (value < end) {
- buf = Character.toLowerCase(chars[value++]);
+ buf = EncodingHelper.toLowerCase(chars[value++]);
if (sp >= sbuf.length) {
char[]tmp = new char[sbuf.length << 1];
System.arraycopy(sbuf, 0, tmp, 0, sbuf.length);
diff --git a/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java b/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java
index 397b05ce..dda5b733 100644
--- a/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java
+++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java
@@ -20,70 +20,42 @@
package jdk.nashorn.internal.runtime.regexp.joni;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
final class ApplyCaseFold {
// i_apply_case_fold
- public void apply(int from, int[]to, int length, Object o) {
+ public void apply(int from, int to, Object o) {
ApplyCaseFoldArg arg = (ApplyCaseFoldArg)o;
ScanEnvironment env = arg.env;
CClassNode cc = arg.cc;
BitSet bs = cc.bs;
- if (length == 1) {
- boolean inCC = cc.isCodeInCC(from);
+ boolean inCC = cc.isCodeInCC(from);
- if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) {
- if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) {
- if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
- cc.addCodeRange(env, to[0], to[0]);
- } else {
- /* /(?i:[^A-C])/.match("a") ==> fail. */
- bs.set(to[0]);
- }
- }
- } else {
- if (inCC) {
- if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
- if (cc.isNot()) cc.clearNotFlag();
- cc.addCodeRange(env, to[0], to[0]);
- } else {
- if (cc.isNot()) {
- bs.clear(to[0]);
- } else {
- bs.set(to[0]);
- }
- }
+ if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) {
+ if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) {
+ if (to >= BitSet.SINGLE_BYTE_SIZE) {
+ cc.addCodeRange(env, to, to);
+ } else {
+ /* /(?i:[^A-C])/.match("a") ==> fail. */
+ bs.set(to);
}
- } // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
-
+ }
} else {
- if (cc.isCodeInCC(from) && (!Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS || !cc.isNot())) {
- StringNode node = null;
- for (int i=0; i<length; i++) {
- if (i == 0) {
- node = new StringNode();
- /* char-class expanded multi-char only
- compare with string folded at match time. */
- node.setAmbig();
- }
- node.catCode(to[i]);
- }
-
- ConsAltNode alt = ConsAltNode.newAltNode(node, null);
-
- if (arg.tail == null) {
- arg.altRoot = alt;
+ if (inCC) {
+ if (to >= BitSet.SINGLE_BYTE_SIZE) {
+ if (cc.isNot()) cc.clearNotFlag();
+ cc.addCodeRange(env, to, to);
} else {
- arg.tail.setCdr(alt);
+ if (cc.isNot()) {
+ bs.clear(to);
+ } else {
+ bs.set(to);
+ }
}
- arg.tail = alt;
}
-
- }
+ } // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
}
diff --git a/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java b/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java
index df4b125b..b897a8cb 100644
--- a/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java
+++ b/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java
@@ -58,8 +58,8 @@ class ByteCodeMachine extends StackMachine {
int end1 = s1 + mbLen;
while (s1 < end1) {
- char c1 = Character.toLowerCase(chars[s1++]);
- char c2 = Character.toLowerCase(chars[s2++]);
+ char c1 = EncodingHelper.toLowerCase(chars[s1++]);
+ char c2 = EncodingHelper.toLowerCase(chars[s2++]);
if (c1 != c2) {
return false;
@@ -367,7 +367,7 @@ class ByteCodeMachine extends StackMachine {
}
private void opExact1IC() {
- if (s >= range || code[ip] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+ if (s >= range || code[ip] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
ip++;
sprev = sbegin; // break;
}
@@ -380,10 +380,10 @@ class ByteCodeMachine extends StackMachine {
char[] bs = regex.templates[code[ip++]];
int ps = code[ip++];
- while (tlen-- > 0) if (bs[ps++] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+ while (tlen-- > 0) if (bs[ps++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
} else {
- while (tlen-- > 0) if (code[ip++] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+ while (tlen-- > 0) if (code[ip++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
}
sprev = s - 1;
}
diff --git a/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java b/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
index afbb1b20..0c9c8ab4 100644
--- a/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
+++ b/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
@@ -93,43 +93,80 @@ public final class EncodingHelper {
return s;
}
- public static int mbcToCode(byte[] bytes, int p, int end) {
- int code = 0;
- for (int i = p; i < end; i++) {
- code = (code << 8) | (bytes[i] & 0xff);
- }
- return code;
- }
-
public static int mbcodeStartPosition() {
return 0x80;
}
public static char[] caseFoldCodesByString(int flag, char c) {
- if (Character.isUpperCase(c)) {
- return new char[] {Character.toLowerCase(c)};
- } else if (Character.isLowerCase(c)) {
- return new char[] {Character.toUpperCase(c)};
- } else {
- return EMPTYCHARS;
+ char[] codes = EMPTYCHARS;
+ final char upper = toUpperCase(c);
+
+ if (upper != toLowerCase(upper)) {
+ int count = 0;
+ char ch = 0;
+
+ do {
+ final char u = toUpperCase(ch);
+ if (u == upper && ch != c) {
+ // Almost all characters will return array of length 1, very few 2 or 3, so growing by one is fine.
+ codes = count == 0 ? new char[1] : Arrays.copyOf(codes, count + 1);
+ codes[count++] = ch;
+ }
+ } while (ch++ < 0xffff);
}
+ return codes;
}
public static void applyAllCaseFold(int flag, ApplyCaseFold fun, Object arg) {
- int[] code = new int[1];
-
for (int c = 0; c < 0xffff; c++) {
- if (Character.getType(c) == Character.LOWERCASE_LETTER) {
+ if (Character.isLowerCase(c)) {
+ final int upper = toUpperCase(c);
- int upper = code[0] = Character.toUpperCase(c);
- fun.apply(c, code, 1, arg);
+ if (upper != c) {
+ fun.apply(c, upper, arg);
+ }
+ }
+ }
- code[0] = c;
- fun.apply(upper, code, 1, arg);
+ // Some characters have multiple lower case variants, hence we need to do a second run
+ for (int c = 0; c < 0xffff; c++) {
+ if (Character.isLowerCase(c)) {
+ final int upper = toUpperCase(c);
+
+ if (upper != c) {
+ fun.apply(upper, c, arg);
+ }
}
}
}
+ public static char toLowerCase(char c) {
+ return (char)toLowerCase((int)c);
+ }
+
+ public static int toLowerCase(int c) {
+ if (c < 128) {
+ return ('A' <= c && c <= 'Z') ? (c + ('a' - 'A')) : c;
+ }
+ // Do not convert non-ASCII upper case character to ASCII lower case.
+ int lower = Character.toLowerCase(c);
+ return (lower < 128) ? c : lower;
+
+ }
+
+ public static char toUpperCase(char c) {
+ return (char)toUpperCase((int)c);
+ }
+
+ public static int toUpperCase(int c) {
+ if (c < 128) {
+ return ('a' <= c && c <= 'z') ? c + ('A' - 'a') : c;
+ }
+ // Do not convert non-ASCII lower case character to ASCII upper case.
+ int upper = Character.toUpperCase(c);
+ return (upper < 128) ? c : upper;
+ }
+
public static int[] ctypeCodeRange(int ctype, IntHolder sbOut) {
sbOut.value = 0x100; // use bitset for codes smaller than 256
int[] range = null;
diff --git a/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java b/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java
index 758679a2..5b2eac97 100644
--- a/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java
+++ b/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java
@@ -168,7 +168,7 @@ public abstract class SearchAlgorithm {
char[] chars, int p, int end) {
while (tP < tEnd) {
- if (t[tP++] != Character.toLowerCase(chars[p++])) return false;
+ if (t[tP++] != EncodingHelper.toLowerCase(chars[p++])) return false;
}
return true;
}
diff --git a/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/src/jdk/nashorn/internal/runtime/resources/Messages.properties
index 47248fce..c98c1c7c 100644
--- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties
+++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -138,6 +138,7 @@ type.error.no.method.matches.args=Can not invoke method {0} with the passed argu
type.error.method.not.constructor=Java method {0} can't be used as a constructor.
type.error.env.not.object=$ENV must be an Object.
type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
+type.error.new.on.nonpublic.javatype=new cannot be used with non-public java type {0}.
range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
range.error.dataview.offset=Offset is outside the bounds of the DataView
diff --git a/test/script/basic/JDK-8030202.js b/test/script/basic/JDK-8030202.js
new file mode 100644
index 00000000..6cf56475
--- /dev/null
+++ b/test/script/basic/JDK-8030202.js
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, 2014, 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-8030202: Nashorn: Multiple RegExp#ignoreCase issues
+ *
+ * @test
+ * @run
+ */
+
+print(/\u2160/i.test("\u2170"));
+print(/[\u2160]/i.test("\u2170"));
+print(/\u2170/i.test("\u2160"));
+print(/[\u2170]/i.test("\u2160"));
+
+print(/\u0130/i.test("\u0069"));
+print(/[\u0130]/i.test("\u0069"));
+print(/\u0069/i.test("\u0130"));
+print(/[\u0069]/i.test("\u0130"));
+
+print(/\u1e9e/i.test("\u00df"));
+print(/[\u1e9e]/i.test("\u00df"));
+print(/\u00df/i.test("\u1e9e"));
+print(/[\u00df]/i.test("\u1e9e"));
+
+print(/[^\u1e9e]/i.test("\u00df"));
+print(/[^\u00df]/i.test("\u1e9e"));
+
+print(/\u0345{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/\u0399{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/\u03b9{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/\u1fbe{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+
+print(/[\u0345]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/[\u0399]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/[\u03b9]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/[\u1fbe]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
diff --git a/test/script/basic/JDK-8030202.js.EXPECTED b/test/script/basic/JDK-8030202.js.EXPECTED
new file mode 100644
index 00000000..7c73d8c0
--- /dev/null
+++ b/test/script/basic/JDK-8030202.js.EXPECTED
@@ -0,0 +1,22 @@
+true
+true
+true
+true
+false
+false
+false
+false
+false
+false
+false
+false
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
diff --git a/test/script/basic/JDK-8043930.js b/test/script/basic/JDK-8043930.js
new file mode 100644
index 00000000..a89b3541
--- /dev/null
+++ b/test/script/basic/JDK-8043930.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-8043930: TypeError when attemping to create an instance of non-public class could be better
+ *
+ * @test
+ * @run
+ */
+
+var NonPublicClass = Java.type("jdk.nashorn.test.models.NonPublicClass");
+try {
+ var obj = new NonPublicClass();
+ fail("Expected TypeError to be thrown!");
+} catch (e) {
+ print(e);
+}
diff --git a/test/script/basic/JDK-8043930.js.EXPECTED b/test/script/basic/JDK-8043930.js.EXPECTED
new file mode 100644
index 00000000..ee5cf9dc
--- /dev/null
+++ b/test/script/basic/JDK-8043930.js.EXPECTED
@@ -0,0 +1 @@
+TypeError: new cannot be used with non-public java type jdk.nashorn.test.models.NonPublicClass.
diff --git a/test/script/basic/JDK-8044520.js b/test/script/basic/JDK-8044520.js
new file mode 100644
index 00000000..edcaa116
--- /dev/null
+++ b/test/script/basic/JDK-8044520.js
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2014, 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-8044520: Nashorn cannot execute node.js's express module
+ *
+ * @test
+ * @run
+ */
+
+function checkNullProto() {
+ var obj = {};
+ obj.__proto__ = null;
+ var proto = Object.getPrototypeOf(obj);
+ if (typeof proto != 'object' || proto !== null) {
+ fail("__proto__ can't be set to null!");
+ }
+}
+
+checkNullProto();
+
+function checkSetProto(proto) {
+ var obj = {};
+ obj.__proto__ = proto;
+ if (Object.getPrototypeOf(obj) !== Object.prototype) {
+ fail("obj.__proto__ set not ignored for " + proto);
+ }
+}
+
+checkSetProto(undefined);
+checkSetProto(42);
+checkSetProto(false);
+checkSetProto("hello");
+
+function checkLiteralSetProto(proto) {
+ var obj = { __proto__: proto };
+ if (obj.__proto__ !== Object.prototype) {
+ fail("object literal _proto__ set not ignored for " + proto);
+ }
+}
+
+checkLiteralSetProto(undefined);
+checkLiteralSetProto(34);
+checkLiteralSetProto(true);
+checkLiteralSetProto("world");
+
+function checkNullProtoFromLiteral() {
+ var obj = { __proto__: null };
+ var proto = Object.getPrototypeOf(obj);
+ if (typeof proto != 'object' || proto !== null) {
+ fail("__proto__ can't be set to null!");
+ }
+}
+
+checkNullProtoFromLiteral();
+
+function checkSetPrototypeOf(proto) {
+ try {
+ Object.setPrototypeOf({}, proto);
+ fail("should have thrown error for " + proto);
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("should have thrown TypeError, got " + e);
+ }
+ }
+}
+
+checkSetPrototypeOf(undefined);
+checkSetPrototypeOf(43);
+checkSetPrototypeOf(false);
+checkSetPrototypeOf("nashorn");
+
+function checkNullSetPrototypeOf() {
+ var obj = { };
+ Object.setPrototypeOf(obj, null);
+ var proto = Object.getPrototypeOf(obj);
+ if (typeof proto != 'object' || proto !== null) {
+ fail("__proto__ can't be set to null!");
+ }
+}
+
+checkNullSetPrototypeOf();
+
+var desc = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__");
+
+function checkProtoGetterOnPrimitive(value) {
+ // call __proto__ getter on primitive - check ToObject
+ // is called on 'this' value as per draft spec
+ if (desc.get.call(value) !== Object(value).__proto__) {
+ fail("can't call __proto__ getter on " + value);
+ }
+}
+
+checkProtoGetterOnPrimitive(32);
+checkProtoGetterOnPrimitive(false);
+checkProtoGetterOnPrimitive("great!");
+
+function checkProtoSetterOnNonObjectThis(self) {
+ try {
+ desc.set.call(self);
+ fail("should have thrown TypeError");
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("should throw TypeError on non-object self, got " +e);
+ }
+ }
+}
+
+checkProtoSetterOnNonObjectThis(undefined);
+checkProtoSetterOnNonObjectThis(null);
+
+function checkProtoSetterReturnValue(obj, p) {
+ if (typeof desc.set.call(obj, p) != "undefined") {
+ fail("__proto__ setter does not return undefined: " + obj + " " + p);
+ }
+}
+
+// try non-object 'this'. setter is expected to return undefined.
+checkProtoSetterReturnValue(23);
+checkProtoSetterReturnValue(false);
+checkProtoSetterReturnValue("foo");
+
+// set proper __proto__. Still return value is undefined.
+checkProtoSetterReturnValue({}, {});
+checkProtoSetterReturnValue({}, null);
diff --git a/test/script/basic/JDK-8044612.js b/test/script/basic/JDK-8044612.js
new file mode 100644
index 00000000..6980cd1b
--- /dev/null
+++ b/test/script/basic/JDK-8044612.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 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-8044612: StringIndexOutOfBoundException in NativeRegExp.appendReplacement
+ *
+ * @test
+ * @run
+ */
+
+if ("hello".replace("h", "$") != "$ello") {
+ fail("String.prototype.replace failed to handle '$' as replacement");
+}
+
+if ("hello".replace("o", "$x") != "hell$x") {
+ fail("String.prototype.replace failed to handle '$x' as replacement");
+}
diff --git a/test/script/basic/JDK-8044695.js b/test/script/basic/JDK-8044695.js
new file mode 100644
index 00000000..2e7b7742
--- /dev/null
+++ b/test/script/basic/JDK-8044695.js
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2014, 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-8044695: __stack__ becomes visible in Error properties
+ *
+ * @test
+ * @run
+ */
+
+var e = new Error();
+// access stack to force __stack__
+e.stack;
+var jsonStr = JSON.stringify(e);
+if (jsonStr != "{}") {
+ fail("JSON string is not {}, it is " + jsonStr);
+}
diff --git a/test/script/basic/JDK-8044750.js b/test/script/basic/JDK-8044750.js
new file mode 100644
index 00000000..ee6fa4d5
--- /dev/null
+++ b/test/script/basic/JDK-8044750.js
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2014, 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-8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
+ *
+ * @test
+ * @run
+ */
+
+__noSuchProperty__ = function(name) {
+ return 1;
+}
+
+function func(obj) {
+ with(obj) {
+ // this "foo" getter site becomes megamorphic
+ // due to different 'with' scope objects.
+ foo;
+ }
+}
+
+for (var i = 0; i < 20; i++) {
+ var obj = {};
+ obj.foo = i;
+ obj[i] = i;
+ func(obj);
+}
+
+// pass a 'with' scope object that does not have 'foo'.
+// callsite inside func should see __noSuchProperty__
+// hook on global scope object.
+func({});
diff --git a/test/script/nosecurity/JDK-8044798.js b/test/script/nosecurity/JDK-8044798.js
new file mode 100644
index 00000000..dc1a7478
--- /dev/null
+++ b/test/script/nosecurity/JDK-8044798.js
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2014, 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-8044798: API for debugging Nashorn
+ *
+ * @test
+ * @run
+ */
+
+// basic API exercise checks
+
+var Arrays = Java.type("java.util.Arrays");
+var CharArray = Java.type("char[]");
+var DebuggerSupport = Java.type("jdk.nashorn.internal.runtime.DebuggerSupport");
+var DebuggerValueDesc = Java.type("jdk.nashorn.internal.runtime.DebuggerSupport.DebuggerValueDesc");
+
+var valueDescFields = DebuggerValueDesc.class.declaredFields;
+Arrays.sort(valueDescFields, function(f1, f2) f1.name.compareTo(f2.name));
+var keyField;
+for each (var f in valueDescFields) {
+ if (f.name == "key") {
+ keyField = f;
+ }
+ f.accessible = true;
+}
+
+var debuggerSupportMethods = DebuggerSupport.class.declaredMethods;
+
+// methods of DebuggerSupport that we use
+var evalMethod, valueInfoMethod, valueInfosMethod;
+var getSourceInfoMethod, valueAsStringMethod;
+
+for each (var m in debuggerSupportMethods) {
+ m.accessible = true;
+ switch (m.name) {
+ case "eval":
+ evalMethod = m;
+ break;
+ case "valueInfo":
+ if (m.parameterCount == 3) {
+ valueInfoMethod = m;
+ }
+ break;
+ case "valueInfos":
+ valueInfosMethod = m;
+ break;
+ case "valueAsString":
+ valueAsStringMethod = m;
+ break;
+ case "getSourceInfo":
+ getSourceInfoMethod = m;
+ break;
+ }
+}
+
+// eval
+var value = evalMethod.invoke(null, null, null, "33 + 55", false);
+print(value);
+
+// valueInfo
+var info = valueInfoMethod.invoke(null, "apply", Function, true);
+for each (var f in valueDescFields) {
+ print(f.name, "=", f.get(info));
+}
+
+// valueInfo - user defined object
+var info = valueInfoMethod.invoke(null, "foo", { foo: 343 }, true);
+for each (var f in valueDescFields) {
+ print(f.name, "=", f.get(info));
+}
+
+// valueInfos
+var infos = valueInfosMethod.invoke(null, Object, true);
+Arrays.sort(infos, function (i1, i2) keyField.get(i1).compareTo(keyField.get(i2)));
+
+for each (var info in infos) {
+ for each (var f in valueDescFields) {
+ print(f.name, "=", f.get(info));
+ }
+}
+
+// valueInfos - user defined object
+var infos = valueInfosMethod.invoke(null, { foo: 34, bar: "hello" }, true);
+Arrays.sort(infos, function (i1, i2) keyField.get(i1).compareTo(keyField.get(i2)));
+
+for each (var info in infos) {
+ for each (var f in valueDescFields) {
+ print(f.name, "=", f.get(info));
+ }
+}
+
+// valueAsString
+function printValue(value) {
+ print(valueAsStringMethod.invoke(null, value));
+}
+
+printValue(undefined);
+printValue(null);
+printValue("hello");
+printValue(Math.PI);
+printValue(this);
+
+// The below are not part of DebuggerSupport. But we need these to
+// test DebuggerSupport.getSourceInfo etc. which need compiled script class
+
+var Source = Java.type("jdk.nashorn.internal.runtime.Source");
+var Context = Java.type("jdk.nashorn.internal.runtime.Context");
+var sourceCls = Source.class;
+var errorMgrCls = Java.type("jdk.nashorn.internal.runtime.ErrorManager").class;
+var booleanCls = Java.type("java.lang.Boolean").TYPE;
+
+// private compile method of Context class
+var compileMethod = Context.class.getDeclaredMethod("compile",
+ sourceCls, errorMgrCls, booleanCls);
+compileMethod.accessible = true;
+
+var scriptCls = compileMethod.invoke(Context.context,
+ Source.sourceFor("test", "print('hello')"),
+ new Context.ThrowErrorManager(), false);
+
+var SCRIPT_CLASS_NAME_PREFIX = "jdk.nashorn.internal.scripts.Script$";
+print("script class name pattern satisfied? " +
+ scriptCls.name.startsWith(SCRIPT_CLASS_NAME_PREFIX));
+
+var srcInfo = getSourceInfoMethod.invoke(null, scriptCls);
+var srcInfoFields = srcInfo.class.declaredFields;
+Arrays.sort(srcInfoFields, function(f1, f2) f1.name.compareTo(f2.name));
+
+print("Source info");
+for each (var f in srcInfoFields) {
+ f.accessible = true;
+ var fieldValue = f.get(srcInfo);
+ if (fieldValue instanceof CharArray) {
+ fieldValue = new java.lang.String(fieldValue);
+ }
+
+ print(f.name, "=", fieldValue);
+}
diff --git a/test/script/nosecurity/JDK-8044798.js.EXPECTED b/test/script/nosecurity/JDK-8044798.js.EXPECTED
new file mode 100644
index 00000000..2a21328c
--- /dev/null
+++ b/test/script/nosecurity/JDK-8044798.js.EXPECTED
@@ -0,0 +1,104 @@
+88
+expandable = false
+key = apply
+valueAsObject = function Function() { [native code] }
+valueAsString = function Function() { [native code] }
+expandable = true
+key = foo
+valueAsObject = [object Object]
+valueAsString = {foo: 343}
+expandable = false
+key = bindProperties
+valueAsObject = function bindProperties() { [native code] }
+valueAsString = function bindProperties() { [native code] }
+expandable = false
+key = create
+valueAsObject = function create() { [native code] }
+valueAsString = function create() { [native code] }
+expandable = false
+key = defineProperties
+valueAsObject = function defineProperties() { [native code] }
+valueAsString = function defineProperties() { [native code] }
+expandable = false
+key = defineProperty
+valueAsObject = function defineProperty() { [native code] }
+valueAsString = function defineProperty() { [native code] }
+expandable = false
+key = freeze
+valueAsObject = function freeze() { [native code] }
+valueAsString = function freeze() { [native code] }
+expandable = false
+key = getOwnPropertyDescriptor
+valueAsObject = function getOwnPropertyDescriptor() { [native code] }
+valueAsString = function getOwnPropertyDescriptor() { [native code] }
+expandable = false
+key = getOwnPropertyNames
+valueAsObject = function getOwnPropertyNames() { [native code] }
+valueAsString = function getOwnPropertyNames() { [native code] }
+expandable = false
+key = getPrototypeOf
+valueAsObject = function getPrototypeOf() { [native code] }
+valueAsString = function getPrototypeOf() { [native code] }
+expandable = false
+key = isExtensible
+valueAsObject = function isExtensible() { [native code] }
+valueAsString = function isExtensible() { [native code] }
+expandable = false
+key = isFrozen
+valueAsObject = function isFrozen() { [native code] }
+valueAsString = function isFrozen() { [native code] }
+expandable = false
+key = isSealed
+valueAsObject = function isSealed() { [native code] }
+valueAsString = function isSealed() { [native code] }
+expandable = false
+key = keys
+valueAsObject = function keys() { [native code] }
+valueAsString = function keys() { [native code] }
+expandable = false
+key = length
+valueAsObject = 1
+valueAsString = 1
+expandable = false
+key = name
+valueAsObject = Object
+valueAsString = "Object"
+expandable = false
+key = preventExtensions
+valueAsObject = function preventExtensions() { [native code] }
+valueAsString = function preventExtensions() { [native code] }
+expandable = false
+key = prototype
+valueAsObject = [object Object]
+valueAsString = {toString: function toString() { [native code] }, toLocaleString: function toLocaleString() { [native code] }, valueOf: function valueOf() { [native code] }, hasOwnProperty: function hasOwnProperty() { [native code] }, isPrototypeOf: function isPrototypeOf() { [native code] }, propertyIsEnumerable: function propertyIsEnumerable() { [native code] }, constructor: function Object() { [native code] }, __proto__: null}
+expandable = false
+key = seal
+valueAsObject = function seal() { [native code] }
+valueAsString = function seal() { [native code] }
+expandable = false
+key = setIndexedPropertiesToExternalArrayData
+valueAsObject = function setIndexedPropertiesToExternalArrayData() { [native code] }
+valueAsString = function setIndexedPropertiesToExternalArrayData() { [native code] }
+expandable = false
+key = setPrototypeOf
+valueAsObject = function setPrototypeOf() { [native code] }
+valueAsString = function setPrototypeOf() { [native code] }
+expandable = false
+key = bar
+valueAsObject = hello
+valueAsString = "hello"
+expandable = false
+key = foo
+valueAsObject = 34
+valueAsString = 34
+undefined
+null
+"hello"
+3.141592653589793
+[object global]
+script class name pattern satisfied? true
+Source info
+content = print('hello')
+hash = 1655359881
+name = test
+url = null
diff --git a/test/script/nosecurity/debuggersupportapi.js b/test/script/nosecurity/debuggersupportapi.js
new file mode 100644
index 00000000..f2fa1014
--- /dev/null
+++ b/test/script/nosecurity/debuggersupportapi.js
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, 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-8044798: API for debugging Nashorn
+ *
+ * @test
+ * @run
+ */
+
+// Basic API class, method, field existence checks.
+
+// The following classes and the associated methods and fields are used as
+// private debugger interface. Though private/implementation defined, nashorn
+// code should not be changed to remove these classes, fields and methods.
+// The test takes signatures of debugger interface and stores in .EXPECTED file.
+// If any incompatible change is made to nashorn to break any of these, this
+// test will fail.
+
+var Arrays = Java.type("java.util.Arrays");
+var DebuggerSupport = Java.type("jdk.nashorn.internal.runtime.DebuggerSupport");
+
+print(DebuggerSupport.class);
+print();
+var methods = DebuggerSupport.class.declaredMethods;
+Arrays.sort(methods, function(m1, m2) m1.name.compareTo(m2.name));
+for each (var mth in methods) {
+ switch (mth.name) {
+ case "eval":
+ case "notifyInvoke":
+ case "getSourceInfo":
+ case "valueAsString":
+ case "valueInfos":
+ print(mth);
+ break;
+ case "valueInfo":
+ if (mth.parameterCount == 3) {
+ print(mth);
+ }
+ break;
+ }
+}
+print();
+
+var DebuggerValueDesc = Java.type("jdk.nashorn.internal.runtime.DebuggerSupport.DebuggerValueDesc");
+print(DebuggerValueDesc.class);
+print();
+var fields = DebuggerValueDesc.class.declaredFields;
+Arrays.sort(fields, function(f1, f2) f1.name.compareTo(f2.name));
+for each (var fld in fields) {
+ switch (fld.name) {
+ case "key":
+ case "expandable":
+ case "valueAsObject":
+ case "valueAsString":
+ print(fld);
+ }
+}
+print();
+
+var SourceInfo = Java.type("jdk.nashorn.internal.runtime.DebuggerSupport.SourceInfo");
+print(SourceInfo.class);
+print();
+var fields = SourceInfo.class.declaredFields;
+Arrays.sort(fields, function(f1, f2) f1.name.compareTo(f2.name));
+for each (var fld in fields) {
+ switch (fld.name) {
+ case "name":
+ case "hash":
+ case "url":
+ case "content":
+ print(fld);
+ }
+}
diff --git a/test/script/nosecurity/debuggersupportapi.js.EXPECTED b/test/script/nosecurity/debuggersupportapi.js.EXPECTED
new file mode 100644
index 00000000..0db8b30c
--- /dev/null
+++ b/test/script/nosecurity/debuggersupportapi.js.EXPECTED
@@ -0,0 +1,22 @@
+class jdk.nashorn.internal.runtime.DebuggerSupport
+
+static java.lang.Object jdk.nashorn.internal.runtime.DebuggerSupport.eval(jdk.nashorn.internal.runtime.ScriptObject,java.lang.Object,java.lang.String,boolean)
+static jdk.nashorn.internal.runtime.DebuggerSupport$SourceInfo jdk.nashorn.internal.runtime.DebuggerSupport.getSourceInfo(java.lang.Class)
+static void jdk.nashorn.internal.runtime.DebuggerSupport.notifyInvoke(java.lang.invoke.MethodHandle)
+static java.lang.String jdk.nashorn.internal.runtime.DebuggerSupport.valueAsString(java.lang.Object)
+static jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc jdk.nashorn.internal.runtime.DebuggerSupport.valueInfo(java.lang.String,java.lang.Object,boolean)
+static jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc[] jdk.nashorn.internal.runtime.DebuggerSupport.valueInfos(java.lang.Object,boolean)
+
+class jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc
+
+final boolean jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc.expandable
+final java.lang.String jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc.key
+final java.lang.Object jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc.valueAsObject
+final java.lang.String jdk.nashorn.internal.runtime.DebuggerSupport$DebuggerValueDesc.valueAsString
+
+class jdk.nashorn.internal.runtime.DebuggerSupport$SourceInfo
+
+final char[] jdk.nashorn.internal.runtime.DebuggerSupport$SourceInfo.content
+final int jdk.nashorn.internal.runtime.DebuggerSupport$SourceInfo.hash
+final java.lang.String jdk.nashorn.internal.runtime.DebuggerSupport$SourceInfo.name
+final java.net.URL jdk.nashorn.internal.runtime.DebuggerSupport$SourceInfo.url
diff --git a/test/script/nosecurity/nosecurity.js b/test/script/nosecurity/nosecurity.js
new file mode 100644
index 00000000..688af8cf
--- /dev/null
+++ b/test/script/nosecurity/nosecurity.js
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/**
+ * 8043443: Test framework changes to run script tests without security manager
+ * @test
+ * @run
+ */
+
+var System = Java.type("java.lang.System");
+
+if (System.securityManager != null) {
+ fail("SecurityManager is set!");
+}
diff --git a/test/src/jdk/nashorn/api/scripting/ScopeTest.java b/test/src/jdk/nashorn/api/scripting/ScopeTest.java
index dc27d826..e2aec242 100644
--- a/test/src/jdk/nashorn/api/scripting/ScopeTest.java
+++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java
@@ -510,6 +510,23 @@ public class ScopeTest {
assertEquals(e.eval("x", newCtxt), 2);
}
+ // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
+ @Test
+ public static void testMegamorphicGetInGlobal() throws Exception {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine engine = m.getEngineByName("nashorn");
+ final String script = "foo";
+ // "foo" is megamorphic because of different global scopes.
+ // Make sure ScriptContext variable search works even after
+ // it becomes megamorphic.
+ for (int index = 0; index < 25; index++) {
+ final Bindings bindings = new SimpleBindings();
+ bindings.put("foo", index);
+ final Number value = (Number)engine.eval(script, bindings);
+ assertEquals(index, value.intValue());
+ }
+ }
+
/**
* Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
*/
diff --git a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java
index 241f22c3..30eaefca 100644
--- a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java
+++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java
@@ -29,6 +29,8 @@ import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
@@ -276,4 +278,31 @@ public class ScriptObjectMirrorTest {
"({ toString: function() { return 'foo' } })");
assertEquals("foo", obj.to(String.class));
}
+
+ // @bug 8044000: Access to undefined property yields "null" instead of "undefined"
+ @Test
+ public void mapScriptObjectMirrorCallsiteTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine engine = m.getEngineByName("nashorn");
+ final String TEST_SCRIPT = "typeof obj.foo";
+
+ final Bindings global = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
+ engine.eval("var obj = java.util.Collections.emptyMap()");
+ // this will drive callsite "obj.foo" of TEST_SCRIPT
+ // to use "obj instanceof Map" as it's guard
+ engine.eval(TEST_SCRIPT, global);
+ // redefine 'obj' to be a script object
+ engine.eval("obj = {}");
+
+ final Bindings newGlobal = engine.createBindings();
+ // transfer 'obj' from default global to new global
+ // new global will get a ScriptObjectMirror wrapping 'obj'
+ newGlobal.put("obj", global.get("obj"));
+
+ // Every ScriptObjectMirror is a Map! If callsite "obj.foo"
+ // does not see the new 'obj' is a ScriptObjectMirror, it'll
+ // continue to use Map's get("obj.foo") instead of ScriptObjectMirror's
+ // getMember("obj.foo") - thereby getting null instead of undefined
+ assertEquals("undefined", engine.eval(TEST_SCRIPT, newGlobal));
+ }
}