--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java Thu Nov 06 13:15:52 2014 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/MethodEmitter.java Thu Nov 06 13:17:47 2014 +0100
@@ -1591,7 +1591,7 @@
/**
* Abstraction for performing a conditional jump of any type
*
- * @see MethodEmitter.Condition
+ * @see Condition
*
* @param cond the condition to test
* @param trueLabel the destination label is condition is true
@@ -2217,6 +2217,10 @@
* @return the method emitter
*/
MethodEmitter dynamicGet(final Type valueType, final String name, final int flags, final boolean isMethod) {
+ if (name.length() > LARGE_STRING_THRESHOLD) { // use getIndex for extremely long names
+ return load(name).dynamicGetIndex(valueType, flags, isMethod);
+ }
+
debug("dynamic_get", name, valueType, getProgramPoint(flags));
Type type = valueType;
@@ -2240,9 +2244,14 @@
* @param name name of property
* @param flags call site flags
*/
- void dynamicSet(final String name, final int flags) {
- assert !isOptimistic(flags);
- debug("dynamic_set", name, peekType());
+ void dynamicSet(final String name, final int flags) {
+ if (name.length() > LARGE_STRING_THRESHOLD) { // use setIndex for extremely long names
+ load(name).swap().dynamicSetIndex(flags);
+ return;
+ }
+
+ assert !isOptimistic(flags);
+ debug("dynamic_set", name, peekType());
Type type = peekType();
if (type.isObject() || type.isBoolean()) { //promote strings to objects etc
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java Thu Nov 06 13:15:52 2014 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java Thu Nov 06 13:17:47 2014 +0100
@@ -25,6 +25,8 @@
package jdk.nashorn.internal.codegen;
+import static jdk.nashorn.internal.codegen.MethodEmitter.LARGE_STRING_THRESHOLD;
+
import java.util.HashMap;
/**
@@ -66,27 +68,28 @@
}
/**
- * Create a uniqueName name in the namespace in the form base$n where n varies
- * .
+ * Create a uniqueName name in the namespace in the form base$n where n varies.
+ * Also truncates very long names that would otherwise break ASM.
+ *
* @param base Base of name. Base will be returned if uniqueName.
- *
* @return Generated uniqueName name.
*/
public String uniqueName(final String base) {
+ final String truncatedBase = base.length() > LARGE_STRING_THRESHOLD ? base.substring(0, LARGE_STRING_THRESHOLD) : base;
for (Namespace namespace = this; namespace != null; namespace = namespace.getParent()) {
final HashMap<String, Integer> namespaceDirectory = namespace.directory;
- final Integer counter = namespaceDirectory.get(base);
+ final Integer counter = namespaceDirectory.get(truncatedBase);
if (counter != null) {
final int count = counter + 1;
- namespaceDirectory.put(base, count);
- return base + '-' + count;
+ namespaceDirectory.put(truncatedBase, count);
+ return truncatedBase + '-' + count;
}
}
- directory.put(base, 0);
+ directory.put(truncatedBase, 0);
- return base;
+ return truncatedBase;
}
@Override
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8047365.js Thu Nov 06 13:17:47 2014 +0100
@@ -0,0 +1,39 @@
+/*
+ * 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-8047365: Very long function names break codegen
+ *
+ * @test
+ * @run
+ */
+
+// string of length 131071, twice the limit of UTF8 strings in ASM
+var longId = Array(0x20000).join("a");
+print(longId.length);
+
+eval("function " + longId + "(){ print('hello world'); }");
+eval("print(typeof " + longId + ")");
+eval("print(" + longId + ".name === longId)");
+eval("print(/a+/.exec(" + longId + ".toString())[0] === longId)");
+eval(longId + "()");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8047365.js.EXPECTED Thu Nov 06 13:17:47 2014 +0100
@@ -0,0 +1,5 @@
+131071
+function
+true
+true
+hello world