8144473: Nashorn code assumes NashornCallSiteDescriptor always
Reviewed-by: hannesw, mhaupt
This commit is contained in:
parent
9739ad81ee
commit
4a435bea6c
@ -1 +1,2 @@
|
||||
DOMLinkerExporter
|
||||
UnderscoreNameLinkerExporter
|
||||
|
129
nashorn/samples/UnderscoreNameLinkerExporter.java
Normal file
129
nashorn/samples/UnderscoreNameLinkerExporter.java
Normal file
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
import jdk.dynalink.CallSiteDescriptor;
|
||||
import jdk.dynalink.CompositeOperation;
|
||||
import jdk.dynalink.NamedOperation;
|
||||
import jdk.dynalink.Operation;
|
||||
import jdk.dynalink.CompositeOperation;
|
||||
import jdk.dynalink.StandardOperation;
|
||||
import jdk.dynalink.linker.GuardingDynamicLinker;
|
||||
import jdk.dynalink.linker.GuardingDynamicLinkerExporter;
|
||||
import jdk.dynalink.linker.GuardedInvocation;
|
||||
import jdk.dynalink.linker.LinkRequest;
|
||||
import jdk.dynalink.linker.LinkerServices;
|
||||
import jdk.dynalink.linker.support.SimpleLinkRequest;
|
||||
|
||||
/**
|
||||
* This is a dynalink pluggable linker (see http://openjdk.java.net/jeps/276).
|
||||
* This linker translater underscore_separated method names to CamelCase names
|
||||
* used in Java APIs.
|
||||
*/
|
||||
public final class UnderscoreNameLinkerExporter extends GuardingDynamicLinkerExporter {
|
||||
static {
|
||||
System.out.println("pluggable dynalink underscore name linker loaded");
|
||||
}
|
||||
|
||||
private static final Pattern UNDERSCORE_NAME = Pattern.compile("_(.)");
|
||||
|
||||
// translate underscore_separated name as a CamelCase name
|
||||
private static String translateToCamelCase(String name) {
|
||||
Matcher m = UNDERSCORE_NAME.matcher(name);
|
||||
StringBuilder buf = new StringBuilder();
|
||||
while (m.find()) {
|
||||
m.appendReplacement(buf, m.group(1).toUpperCase());
|
||||
}
|
||||
m.appendTail(buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
// locate the first standard operation from the call descriptor
|
||||
private static StandardOperation getFirstStandardOperation(final CallSiteDescriptor desc) {
|
||||
final Operation base = NamedOperation.getBaseOperation(desc.getOperation());
|
||||
if (base instanceof StandardOperation) {
|
||||
return (StandardOperation)base;
|
||||
} else if (base instanceof CompositeOperation) {
|
||||
final CompositeOperation cop = (CompositeOperation)base;
|
||||
for(int i = 0; i < cop.getOperationCount(); ++i) {
|
||||
final Operation op = cop.getOperation(i);
|
||||
if (op instanceof StandardOperation) {
|
||||
return (StandardOperation)op;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<GuardingDynamicLinker> get() {
|
||||
final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>();
|
||||
linkers.add(new GuardingDynamicLinker() {
|
||||
@Override
|
||||
public GuardedInvocation getGuardedInvocation(LinkRequest request,
|
||||
LinkerServices linkerServices) throws Exception {
|
||||
final Object self = request.getReceiver();
|
||||
CallSiteDescriptor desc = request.getCallSiteDescriptor();
|
||||
Operation op = desc.getOperation();
|
||||
Object name = NamedOperation.getName(op);
|
||||
// is this a named GET_METHOD?
|
||||
boolean isGetMethod = getFirstStandardOperation(desc) == StandardOperation.GET_METHOD;
|
||||
if (isGetMethod && name instanceof String) {
|
||||
String str = (String)name;
|
||||
if (str.indexOf('_') == -1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String nameStr = translateToCamelCase(str);
|
||||
// create a new call descriptor to use translated name
|
||||
CallSiteDescriptor newDesc = new CallSiteDescriptor(
|
||||
desc.getLookup(),
|
||||
new NamedOperation(NamedOperation.getBaseOperation(op), nameStr),
|
||||
desc.getMethodType());
|
||||
// create a new Link request to link the call site with translated name
|
||||
LinkRequest newRequest = new SimpleLinkRequest(newDesc,
|
||||
request.isCallSiteUnstable(), request.getArguments());
|
||||
// return guarded invocation linking the translated request
|
||||
return linkerServices.getGuardedInvocation(newRequest);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
});
|
||||
return linkers;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#// Usage: jjs -scripting dom_linker_gutenberg.js
|
||||
#// Usage: jjs -cp dom_linker.jar -scripting dom_linker_gutenberg.js
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
|
||||
@ -31,6 +31,9 @@
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
// This script depends on DOM Element dynalink linker!
|
||||
// Without that linker, this script will fail to run!
|
||||
|
||||
// Simple example that demonstrates reading XML Rss feed
|
||||
// to generate a HTML file from script and show it by browser.
|
||||
// Uses XML DOM parser along with DOM element pluggable dynalink linker
|
||||
|
42
nashorn/samples/underscore.js
Normal file
42
nashorn/samples/underscore.js
Normal file
@ -0,0 +1,42 @@
|
||||
#// Usage: jjs -cp underscore_linker.jar -scripting underscore.js
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, 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 script depends on underscore name to CamelCase name
|
||||
// translator dynalink linker! Without that linker, this script
|
||||
// will fail to run!
|
||||
|
||||
var S = java.util.stream.Stream
|
||||
S.of(45, 54654,546,435).for_each(print)
|
||||
print("hello".char_at(2))
|
||||
print(4354.45.value_of())
|
||||
print(java.lang.System.get_properties())
|
50
nashorn/samples/underscore_linker.js
Normal file
50
nashorn/samples/underscore_linker.js
Normal file
@ -0,0 +1,50 @@
|
||||
# underscore name translator dynalink linker example
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015, 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 script assumes you've built jdk9 or using latest
|
||||
// jdk9 image and put the 'bin' directory in the PATH
|
||||
|
||||
$EXEC.throwOnError=true
|
||||
|
||||
// compile UnderscoreNameLinkerExporter
|
||||
`javac -cp ../dist/nashorn.jar UnderscoreNameLinkerExporter.java`
|
||||
|
||||
// make a jar file out of pluggable linker
|
||||
`jar cvf underscore_linker.jar UnderscoreNameLinkerExporter*.class META-INF/`
|
||||
|
||||
// run a sample script that uses pluggable linker
|
||||
// but make sure classpath points to the pluggable linker jar!
|
||||
|
||||
`jjs -cp underscore_linker.jar underscore.js`
|
||||
print($OUT)
|
||||
|
@ -86,9 +86,9 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
|
||||
MH.dropArguments(EMPTY_PROP_SETTER, 0, Object.class);
|
||||
|
||||
private static GuardedInvocation linkBean(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
|
||||
final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor)linkRequest.getCallSiteDescriptor();
|
||||
final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
|
||||
final Object self = linkRequest.getReceiver();
|
||||
switch (desc.getFirstOperation()) {
|
||||
switch (NashornCallSiteDescriptor.getFirstStandardOperation(desc)) {
|
||||
case NEW:
|
||||
if(BeansLinker.isDynamicConstructor(self)) {
|
||||
throw typeError("no.constructor.matches.args", ScriptRuntime.safeToString(self));
|
||||
@ -96,7 +96,7 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
|
||||
if(BeansLinker.isDynamicMethod(self)) {
|
||||
throw typeError("method.not.constructor", ScriptRuntime.safeToString(self));
|
||||
}
|
||||
throw typeError("not.a.function", desc.getFunctionErrorMessage(self));
|
||||
throw typeError("not.a.function", NashornCallSiteDescriptor.getFunctionErrorMessage(desc, self));
|
||||
case CALL:
|
||||
if(BeansLinker.isDynamicConstructor(self)) {
|
||||
throw typeError("constructor.requires.new", ScriptRuntime.safeToString(self));
|
||||
@ -104,7 +104,7 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
|
||||
if(BeansLinker.isDynamicMethod(self)) {
|
||||
throw typeError("no.method.matches.args", ScriptRuntime.safeToString(self));
|
||||
}
|
||||
throw typeError("not.a.function", desc.getFunctionErrorMessage(self));
|
||||
throw typeError("not.a.function", NashornCallSiteDescriptor.getFunctionErrorMessage(desc, self));
|
||||
case CALL_METHOD:
|
||||
throw typeError("no.such.function", getArgument(linkRequest), ScriptRuntime.safeToString(self));
|
||||
case GET_METHOD:
|
||||
@ -115,7 +115,7 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
|
||||
if(NashornCallSiteDescriptor.isOptimistic(desc)) {
|
||||
throw new UnwarrantedOptimismException(UNDEFINED, NashornCallSiteDescriptor.getProgramPoint(desc), Type.OBJECT);
|
||||
}
|
||||
if (desc.getOperand() != null) {
|
||||
if (NashornCallSiteDescriptor.getOperand(desc) != null) {
|
||||
return getInvocation(EMPTY_PROP_GETTER, self, linkerServices, desc);
|
||||
}
|
||||
return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc);
|
||||
@ -125,7 +125,7 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
|
||||
if (strict) {
|
||||
throw typeError("cant.set.property", getArgument(linkRequest), ScriptRuntime.safeToString(self));
|
||||
}
|
||||
if (desc.getOperand() != null) {
|
||||
if (NashornCallSiteDescriptor.getOperand(desc) != null) {
|
||||
return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc);
|
||||
}
|
||||
return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc);
|
||||
@ -168,8 +168,8 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
|
||||
}
|
||||
|
||||
private static GuardedInvocation linkNull(final LinkRequest linkRequest) {
|
||||
final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor)linkRequest.getCallSiteDescriptor();
|
||||
switch (desc.getFirstOperation()) {
|
||||
final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
|
||||
switch (NashornCallSiteDescriptor.getFirstStandardOperation(desc)) {
|
||||
case NEW:
|
||||
case CALL:
|
||||
throw typeError("not.a.function", "null");
|
||||
|
@ -64,9 +64,7 @@ final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, Gu
|
||||
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices)
|
||||
throws Exception {
|
||||
final Object self = request.getReceiver();
|
||||
final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
|
||||
|
||||
return Bootstrap.asTypeSafeReturn(Global.primitiveLookup(request, self), linkerServices, desc);
|
||||
return Bootstrap.asTypeSafeReturn(Global.primitiveLookup(request, self), linkerServices, request.getCallSiteDescriptor());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -32,6 +32,7 @@ import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.invoke.SwitchPoint;
|
||||
import jdk.dynalink.CallSiteDescriptor;
|
||||
import jdk.dynalink.linker.GuardedInvocation;
|
||||
import jdk.dynalink.linker.LinkRequest;
|
||||
import jdk.dynalink.linker.support.Guards;
|
||||
@ -95,14 +96,11 @@ public final class PrimitiveLookup {
|
||||
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
|
||||
final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
|
||||
final MethodHandle protoFilter) {
|
||||
// lookupPrimitive is only ever invoked from NashornPrimitiveLinker,
|
||||
// which is a linker private to Nashorn, therefore the call site
|
||||
// descriptor class will always be NashornCallSiteDescriptor.
|
||||
final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor)request.getCallSiteDescriptor();
|
||||
final String name = desc.getOperand();
|
||||
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
|
||||
final String name = NashornCallSiteDescriptor.getOperand(desc);
|
||||
final FindProperty find = name != null ? wrappedReceiver.findProperty(name, true) : null;
|
||||
|
||||
switch (desc.getFirstOperation()) {
|
||||
switch (NashornCallSiteDescriptor.getFirstStandardOperation(desc)) {
|
||||
case GET_PROPERTY:
|
||||
case GET_ELEMENT:
|
||||
case GET_METHOD:
|
||||
|
Loading…
Reference in New Issue
Block a user