8062624: java.lang.String methods not available on concatenated strings
Reviewed-by: lagergren, attila
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Wed Nov 05 17:07:26 2014 +0100
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Thu Nov 06 13:15:52 2014 +0100
@@ -53,15 +53,34 @@
// Object type arguments of Java method calls, field set and array set.
private static final boolean MIRROR_ALWAYS = Options.getBooleanProperty("nashorn.mirror.always", true);
- private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class);
- private static final MethodHandle EXPORT_NATIVE_ARRAY = new Lookup(MethodHandles.lookup()).findOwnStatic("exportNativeArray", Object.class, NativeArray.class);
- private static final MethodHandle EXPORT_SCRIPT_OBJECT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportScriptObject", Object.class, ScriptObject.class);
- private static final MethodHandle IMPORT_RESULT = new Lookup(MethodHandles.lookup()).findOwnStatic("importResult", Object.class, Object.class);
+ private static final MethodHandle EXPORT_ARGUMENT;
+ private static final MethodHandle EXPORT_NATIVE_ARRAY;
+ private static final MethodHandle EXPORT_SCRIPT_OBJECT;
+ private static final MethodHandle IMPORT_RESULT;
+ private static final MethodHandle FILTER_CONSSTRING;
+
+ static {
+ final Lookup lookup = new Lookup(MethodHandles.lookup());
+ EXPORT_ARGUMENT = lookup.findOwnStatic("exportArgument", Object.class, Object.class);
+ EXPORT_NATIVE_ARRAY = lookup.findOwnStatic("exportNativeArray", Object.class, NativeArray.class);
+ EXPORT_SCRIPT_OBJECT = lookup.findOwnStatic("exportScriptObject", Object.class, ScriptObject.class);
+ IMPORT_RESULT = lookup.findOwnStatic("importResult", Object.class, Object.class);
+ FILTER_CONSSTRING = lookup.findOwnStatic("consStringFilter", Object.class, Object.class);
+ }
private final BeansLinker beansLinker = new BeansLinker();
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ if (linkRequest.getReceiver() instanceof ConsString) {
+ // In order to treat ConsString like a java.lang.String we need a link request with a string receiver.
+ final Object[] arguments = linkRequest.getArguments();
+ arguments[0] = "";
+ final LinkRequest forgedLinkRequest = linkRequest.replaceArguments(linkRequest.getCallSiteDescriptor(), arguments);
+ final GuardedInvocation invocation = getGuardedInvocation(beansLinker, forgedLinkRequest, linkerServices);
+ // If an invocation is found we add a filter that makes it work for both Strings and ConsStrings.
+ return invocation == null ? null : invocation.filterArguments(0, FILTER_CONSSTRING);
+ }
return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
}
@@ -113,6 +132,11 @@
return ScriptUtils.unwrap(arg);
}
+ @SuppressWarnings("unused")
+ private static Object consStringFilter(final Object arg) {
+ return arg instanceof ConsString ? arg.toString() : arg;
+ }
+
private static class NashornBeansLinkerServices implements LinkerServices {
private final LinkerServices linkerServices;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8062624.js Thu Nov 06 13:15:52 2014 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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-8062624: java.lang.String methods not available on concatenated strings
+ *
+ * @test
+ * @run
+ */
+
+function testStringMethods(s) {
+ print(s.startsWith("f"));
+ print(s.endsWith("r"));
+ print(Java.from(s.getBytes()));
+ print(Java.from(s.bytes));
+}
+
+var s = "f";
+testStringMethods(s);
+s = s + "oo";
+testStringMethods(s);
+testStringMethods("abc");
+s += "bar";
+s = "baz" + s;
+testStringMethods(s);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8062624.js.EXPECTED Thu Nov 06 13:15:52 2014 +0100
@@ -0,0 +1,16 @@
+true
+false
+102
+102
+true
+false
+102,111,111
+102,111,111
+false
+false
+97,98,99
+97,98,99
+false
+true
+98,97,122,102,111,111,98,97,114
+98,97,122,102,111,111,98,97,114