-
Notifications
You must be signed in to change notification settings - Fork 850
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
switch to a vmbridge for jdk_11 and above #1070
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -10,23 +10,24 @@ | |||||||||||||||||||
|
||||||||||||||||||||
import java.lang.reflect.AccessibleObject; | ||||||||||||||||||||
import java.lang.reflect.Method; | ||||||||||||||||||||
import java.util.Arrays; | ||||||||||||||||||||
import java.util.Map; | ||||||||||||||||||||
|
||||||||||||||||||||
public abstract class VMBridge | ||||||||||||||||||||
{ | ||||||||||||||||||||
public abstract class VMBridge { | ||||||||||||||||||||
|
||||||||||||||||||||
static final VMBridge instance = makeInstance(); | ||||||||||||||||||||
|
||||||||||||||||||||
private static VMBridge makeInstance() | ||||||||||||||||||||
{ | ||||||||||||||||||||
private static VMBridge makeInstance() { | ||||||||||||||||||||
String[] classNames = { | ||||||||||||||||||||
"org.mozilla.javascript.VMBridge_custom", | ||||||||||||||||||||
"org.mozilla.javascript.jdk11.VMBridge_jdk11", | ||||||||||||||||||||
"org.mozilla.javascript.jdk18.VMBridge_jdk18", | ||||||||||||||||||||
}; | ||||||||||||||||||||
for (int i = 0; i != classNames.length; ++i) { | ||||||||||||||||||||
String className = classNames[i]; | ||||||||||||||||||||
Class<?> cl = Kit.classOrNull(className); | ||||||||||||||||||||
if (cl != null) { | ||||||||||||||||||||
VMBridge bridge = (VMBridge)Kit.newInstanceOrNull(cl); | ||||||||||||||||||||
VMBridge bridge = (VMBridge) Kit.newInstanceOrNull(cl); | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see no code that distinguish between the different JVM versions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Kit.newInstanceOrNull return null in the case of a ClassNotFoundException so this works based on class loading; the code tries first the jdk11 version an if this fails (because we are on jdk8 it falls back to the jdk8 impl) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
rhino/src/org/mozilla/javascript/JavaMembers_jdk11.java Lines 57 to 65 in c538737
|
||||||||||||||||||||
if (bridge != null) { | ||||||||||||||||||||
return bridge; | ||||||||||||||||||||
} | ||||||||||||||||||||
|
@@ -37,49 +38,45 @@ private static VMBridge makeInstance() | |||||||||||||||||||
|
||||||||||||||||||||
/** | ||||||||||||||||||||
* Return a helper object to optimize {@link Context} access. | ||||||||||||||||||||
* <p> | ||||||||||||||||||||
* The runtime will pass the resulting helper object to the subsequent | ||||||||||||||||||||
* calls to {@link #getContext(Object contextHelper)} and | ||||||||||||||||||||
* {@link #setContext(Object contextHelper, Context cx)} methods. | ||||||||||||||||||||
* In this way the implementation can use the helper to cache | ||||||||||||||||||||
* information about current thread to make {@link Context} access faster. | ||||||||||||||||||||
* | ||||||||||||||||||||
* <p>The runtime will pass the resulting helper object to the subsequent calls to {@link | ||||||||||||||||||||
* #getContext(Object contextHelper)} and {@link #setContext(Object contextHelper, Context cx)} | ||||||||||||||||||||
* methods. In this way the implementation can use the helper to cache information about current | ||||||||||||||||||||
* thread to make {@link Context} access faster. | ||||||||||||||||||||
*/ | ||||||||||||||||||||
protected abstract Object getThreadContextHelper(); | ||||||||||||||||||||
|
||||||||||||||||||||
/** | ||||||||||||||||||||
* Get {@link Context} instance associated with the current thread | ||||||||||||||||||||
* or null if none. | ||||||||||||||||||||
* Get {@link Context} instance associated with the current thread or null if none. | ||||||||||||||||||||
* | ||||||||||||||||||||
* @param contextHelper The result of {@link #getThreadContextHelper()} | ||||||||||||||||||||
* called from the current thread. | ||||||||||||||||||||
* @param contextHelper The result of {@link #getThreadContextHelper()} called from the current | ||||||||||||||||||||
* thread. | ||||||||||||||||||||
*/ | ||||||||||||||||||||
protected abstract Context getContext(Object contextHelper); | ||||||||||||||||||||
|
||||||||||||||||||||
/** | ||||||||||||||||||||
* Associate {@link Context} instance with the current thread or remove | ||||||||||||||||||||
* the current association if <code>cx</code> is null. | ||||||||||||||||||||
* Associate {@link Context} instance with the current thread or remove the current association | ||||||||||||||||||||
* if <code>cx</code> is null. | ||||||||||||||||||||
* | ||||||||||||||||||||
* @param contextHelper The result of {@link #getThreadContextHelper()} | ||||||||||||||||||||
* called from the current thread. | ||||||||||||||||||||
* @param contextHelper The result of {@link #getThreadContextHelper()} called from the current | ||||||||||||||||||||
* thread. | ||||||||||||||||||||
*/ | ||||||||||||||||||||
protected abstract void setContext(Object contextHelper, Context cx); | ||||||||||||||||||||
|
||||||||||||||||||||
/** | ||||||||||||||||||||
* In many JVMSs, public methods in private | ||||||||||||||||||||
* classes are not accessible by default (Sun Bug #4071593). | ||||||||||||||||||||
* VMBridge instance should try to workaround that via, for example, | ||||||||||||||||||||
* calling method.setAccessible(true) when it is available. | ||||||||||||||||||||
* The implementation is responsible to catch all possible exceptions | ||||||||||||||||||||
* like SecurityException if the workaround is not available. | ||||||||||||||||||||
* In many JVMSs, public methods in private classes are not accessible by default (Sun Bug | ||||||||||||||||||||
* #4071593). VMBridge instance should try to workaround that via, for example, calling | ||||||||||||||||||||
* method.setAccessible(true) when it is available. The implementation is responsible to catch | ||||||||||||||||||||
* all possible exceptions like SecurityException if the workaround is not available. | ||||||||||||||||||||
* | ||||||||||||||||||||
* @return true if it was possible to make method accessible | ||||||||||||||||||||
* or false otherwise. | ||||||||||||||||||||
* @return true if it was possible to make method accessible or false otherwise. | ||||||||||||||||||||
*/ | ||||||||||||||||||||
protected abstract boolean tryToMakeAccessible(AccessibleObject accessible); | ||||||||||||||||||||
|
||||||||||||||||||||
/** | ||||||||||||||||||||
* Create helper object to create later proxies implementing the specified | ||||||||||||||||||||
* interfaces later. Under JDK 1.3 the implementation can look like: | ||||||||||||||||||||
* Create helper object to create later proxies implementing the specified interfaces later. | ||||||||||||||||||||
* Under JDK 1.3 the implementation can look like: | ||||||||||||||||||||
* | ||||||||||||||||||||
* <pre> | ||||||||||||||||||||
* return java.lang.reflect.Proxy.getProxyClass(..., interfaces). | ||||||||||||||||||||
* getConstructor(new Class[] { | ||||||||||||||||||||
|
@@ -88,22 +85,50 @@ private static VMBridge makeInstance() | |||||||||||||||||||
* | ||||||||||||||||||||
* @param interfaces Array with one or more interface class objects. | ||||||||||||||||||||
*/ | ||||||||||||||||||||
protected abstract Object getInterfaceProxyHelper(ContextFactory cf, | ||||||||||||||||||||
Class<?>[] interfaces); | ||||||||||||||||||||
protected abstract Object getInterfaceProxyHelper(ContextFactory cf, Class<?>[] interfaces); | ||||||||||||||||||||
|
||||||||||||||||||||
/** | ||||||||||||||||||||
* Create proxy object for {@link InterfaceAdapter}. The proxy should call | ||||||||||||||||||||
* {@link InterfaceAdapter#invoke(ContextFactory, Object, Scriptable, | ||||||||||||||||||||
* Object, Method, Object[])} | ||||||||||||||||||||
* as implementation of interface methods associated with | ||||||||||||||||||||
* <code>proxyHelper</code>. {@link Method} | ||||||||||||||||||||
* Create proxy object for {@link InterfaceAdapter}. The proxy should call {@link | ||||||||||||||||||||
* InterfaceAdapter#invoke(ContextFactory, Object, Scriptable, Object, Method, Object[])} as | ||||||||||||||||||||
* implementation of interface methods associated with <code>proxyHelper</code>. {@link Method} | ||||||||||||||||||||
* | ||||||||||||||||||||
* @param proxyHelper The result of the previous call to | ||||||||||||||||||||
* {@link #getInterfaceProxyHelper(ContextFactory, Class[])}. | ||||||||||||||||||||
* @param proxyHelper The result of the previous call to {@link | ||||||||||||||||||||
* #getInterfaceProxyHelper(ContextFactory, Class[])}. | ||||||||||||||||||||
*/ | ||||||||||||||||||||
protected abstract Object newInterfaceProxy(Object proxyHelper, | ||||||||||||||||||||
ContextFactory cf, | ||||||||||||||||||||
InterfaceAdapter adapter, | ||||||||||||||||||||
Object target, | ||||||||||||||||||||
Scriptable topScope); | ||||||||||||||||||||
protected abstract Object newInterfaceProxy( | ||||||||||||||||||||
Object proxyHelper, | ||||||||||||||||||||
ContextFactory cf, | ||||||||||||||||||||
InterfaceAdapter adapter, | ||||||||||||||||||||
Object target, | ||||||||||||||||||||
Scriptable topScope); | ||||||||||||||||||||
|
||||||||||||||||||||
public abstract void discoverPublicMethods(Class<?> clazz, Map<MethodSignature, Method> map); | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be an API change. If someone has implemented |
||||||||||||||||||||
|
||||||||||||||||||||
public static final class MethodSignature { | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The current |
||||||||||||||||||||
private final String name; | ||||||||||||||||||||
private final Class<?>[] args; | ||||||||||||||||||||
|
||||||||||||||||||||
private MethodSignature(String name, Class<?>[] args) { | ||||||||||||||||||||
this.name = name; | ||||||||||||||||||||
this.args = args; | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
public MethodSignature(Method method) { | ||||||||||||||||||||
this(method.getName(), method.getParameterTypes()); | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
@Override | ||||||||||||||||||||
public boolean equals(Object o) { | ||||||||||||||||||||
if (o instanceof MethodSignature) { | ||||||||||||||||||||
MethodSignature ms = (MethodSignature) o; | ||||||||||||||||||||
return ms.name.equals(name) && Arrays.equals(args, ms.args); | ||||||||||||||||||||
} | ||||||||||||||||||||
return false; | ||||||||||||||||||||
} | ||||||||||||||||||||
|
||||||||||||||||||||
@Override | ||||||||||||||||||||
public int hashCode() { | ||||||||||||||||||||
return name.hashCode() ^ args.length; | ||||||||||||||||||||
} | ||||||||||||||||||||
} | ||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not happy with that naming scheme, because it can be confusing
So jdk18 should be renamed to jdk1_8 or just jdk8