8047365: Very long function names break codegen

Reviewed-by: attila, lagergren
This commit is contained in:
Hannes Wallnöfer 2014-11-06 13:17:47 +01:00
parent 0c4006a654
commit ed9bce193a
4 changed files with 68 additions and 12 deletions

View File

@ -1591,7 +1591,7 @@ public class MethodEmitter implements Emitter {
/**
* 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 @@ public class MethodEmitter implements Emitter {
* @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 @@ public class MethodEmitter implements Emitter {
* @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

View File

@ -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 @@ public class Namespace {
}
/**
* Create a uniqueName name in the namespace in the form base$n where n varies
* .
* @param base Base of name. Base will be returned if uniqueName.
* 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

View File

@ -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 + "()");

View File

@ -0,0 +1,5 @@
131071
function
true
true
hello world