szegedi / dynalink Goto Github PK
View Code? Open in Web Editor NEWDynamic Linker Framework for Languages on the JVM
Home Page: http://szegedi.github.com/dynalink/
License: BSD 3-Clause "New" or "Revised" License
Dynamic Linker Framework for Languages on the JVM
Home Page: http://szegedi.github.com/dynalink/
License: BSD 3-Clause "New" or "Revised" License
Hi Attila,
I have found what I believe to be a bug which may have something to do with dynalink's StaticClass. I have not tried to isolate the issue further, it may even be a JDK issue.
The unit test below shows the bug. I use 1.7.0_21 on OS X 10.8.4.
It boils down to a static method throwing an exception when passed an instance of an anonymous class (or a local class, same behaviour), whereas making the same call using a virtual method or a static method with an instance of a regular (public) class succeeds.
Here is the output I get when I run the unit test:
Testsuite: ch.towerworks.allegra.utils.arrays.ops.DynaLinkTest
Tests run: 6, Failures: 0, Errors: 2, Time elapsed: 0.537 sec
Testcase: testStaticAnonymousClass(ch.towerworks.allegra.utils.arrays.ops.DynaLinkTest): Caused an ERROR
JVM cannot find invoker for (StaticClass,double,)Object
java.lang.InternalError: JVM cannot find invoker for (StaticClass,double,)Object
at java.lang.invoke.Invokers.lookupInvoker(Invokers.java:91)
at java.lang.invoke.Invokers.exactInvoker(Invokers.java:73)
at java.lang.invoke.Invokers.erasedInvoker(Invokers.java:99)
at java.lang.invoke.InvokeGeneric.dispatch(InvokeGeneric.java:108)
at java.lang.invoke.InvokeGeneric.dispatchWithConversion(InvokeGeneric.java:117)
at ch.towerworks.allegra.utils.arrays.ops.DynaLinkTest.testStaticAnonymousClass(DynaLinkTest.java:116)
Testcase: testStaticLocalClass(ch.towerworks.allegra.utils.arrays.ops.DynaLinkTest): Caused an ERROR
JVM cannot find invoker for (StaticClass,double,Sqr)Object
java.lang.InternalError: JVM cannot find invoker for (StaticClass,double,Sqr)Object
at java.lang.invoke.Invokers.lookupInvoker(Invokers.java:91)
at java.lang.invoke.Invokers.exactInvoker(Invokers.java:73)
at java.lang.invoke.Invokers.erasedInvoker(Invokers.java:99)
at java.lang.invoke.InvokeGeneric.dispatch(InvokeGeneric.java:108)
at java.lang.invoke.InvokeGeneric.dispatchWithConversion(InvokeGeneric.java:117)
at ch.towerworks.allegra.utils.arrays.ops.DynaLinkTest.testStaticLocalClass(DynaLinkTest.java:108)
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import org.dynalang.dynalink.DefaultBootstrapper;
import org.dynalang.dynalink.beans.StaticClass;
import org.junit.Assert;
import org.junit.Test;
/**
*
@author Hans-Peter Schmid
*/
public class DynaLinkTest {
public interface F {
double apply(double value);
}
public static class Sqrt implements F {
@Override
public double apply(double value) {
return Math.sqrt(value);
}
}
public static class Apply {
public double virt(double value, F func) {
return func.apply(value);
}
public static double stat(double value, F func) {
return func.apply(value);
}
}
@test
public void testVirtual() throws Throwable {
final CallSite fSite = DefaultBootstrapper.bootstrap(MethodHandles.lookup(), "dyn:callMethod:virt", MethodType.methodType(Object.class, Apply.class, double.class, Object.class));
final Object sqrt = fSite.dynamicInvoker().invoke(new Apply(), 100.0, new Sqrt());
Assert.assertEquals(10.0, sqrt);
}
@test
public void testVirtualLocalClass() throws Throwable {
class Sqr implements F {
@Override
public double apply(double value) {
return value * value;
}
}
final CallSite virtSite = DefaultBootstrapper.bootstrap(MethodHandles.lookup(), "dyn:callMethod:virt", MethodType.methodType(Object.class, Apply.class, double.class, Object.class));
final Object sqrt = virtSite.dynamicInvoker().invoke(new Apply(), 10.0, new Sqr());
Assert.assertEquals(100.0, sqrt);
}
@test
public void testVirtualAnonymousClass() throws Throwable {
final CallSite virtSite = DefaultBootstrapper.bootstrap(MethodHandles.lookup(), "dyn:callMethod:virt", MethodType.methodType(Object.class, Apply.class, double.class, Object.class));
final Object sqrt = virtSite.dynamicInvoker().invoke(new Apply(), 10.0, new F() {
@OverRide
public double apply(double value) {
return value * value;
}
});
Assert.assertEquals(100.0, sqrt);
}
@test
public void testStatic() throws Throwable {
final CallSite statSite = DefaultBootstrapper.bootstrap(MethodHandles.lookup(), "dyn:callMethod:stat",
MethodType.methodType(Object.class, StaticClass.class, Object.class, Object.class));
final Object sqr = statSite.dynamicInvoker().invoke(StaticClass.forClass(Apply.class), 100, new Sqrt());
Assert.assertEquals(10.0, sqr);
}
@test
public void testStaticLocalClass() throws Throwable {
class Sqr implements F {
@Override
public double apply(double value) {
return value * value;
}
}
final CallSite statSite = DefaultBootstrapper.bootstrap(MethodHandles.lookup(), "dyn:callMethod:stat",
MethodType.methodType(Object.class, StaticClass.class, Object.class, Object.class));
final Object sqr = statSite.dynamicInvoker().invoke(StaticClass.forClass(Apply.class), 10.0, new Sqr());
Assert.assertEquals(100.0, sqr);
}
@test
public void testStaticAnonymousClass() throws Throwable {
final CallSite statSite = DefaultBootstrapper.bootstrap(MethodHandles.lookup(), "dyn:callMethod:stat",
MethodType.methodType(Object.class, StaticClass.class, Object.class, Object.class));
final Object sqr = statSite.dynamicInvoker().invoke(StaticClass.forClass(Apply.class), 10.0, new F() {
@OverRide
public double apply(double value) {
return value * value;
}
});
Assert.assertEquals(100.0, sqr);
}
}
I've been aware of dynalink for a while and I know it's being used in Nashorn but I'm unclear what it's current status is so re the "pipe dream" described:
"Want to pass objects from Ruby to Python to JavaScript to Java and back within the same JVM? Think it's a pipe dream? Think again."
I was looking here and also googling wondering/hoping there's some simple examples showing this in action (yet?)
And if there were I was wondering what if any constraints/limitations there are - e.g. I myself am mostly interested in interop between java, groovy, and nashorn - but groovy isn't mentioned in the quote above and I don't know if that's because groovy doesn't use dynalink or if it's just happenstance...
The Java Language does not support method overloading by return type but the JVM specification does. It would be good if this could be supported so that languages or tools that use this feature will continue to work.
JVM Spec 4.3.4 : http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.4
"A method signature, defined by the production MethodTypeSignature, encodes the (possibly parameterized) types of the method's formal arguments and of the exceptions it has declared in its throws clause, its (possibly parameterized) return type, and any formal type parameters in the method declaration."
Example: see Proguard http://proguard.sourceforge.net/index.html#manual/usage.html (overloadaggressively)
"Counter-indication: the resulting class files fall within the Java bytecode specification (cfr. The Java Virtual Machine Specification, Second Edition, first paragraphs of Section 4.5 and Section 4.6), even though this kind of overloading is not allowed in the Java language (cfr. The Java Language Specification, Second Edition, Section 8.3 and Section 8.4.7). "
I need access to bootstrap lookup to proper resolve method handles for things like super.invokeMethod().
Is it possible to have a DSL to remove most of the boiler plate.
Any plan to backport jdk.dynalink
?
In order to implement optimized call sites (e.g., inlining cache), the GuardingDynamicLinker will need access to the CallSite so call site specific information can be cached (e.g., current inline depth).
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.