Am 02.07.2013 20:13, schrieb John Rose: [...] > The upshot of all this is that if you encapsulate your CS method calls > in method handles obtained from a BSM or MethodHandles.lookup, your code > won't be sensitive to the dynamic context of those calls.
Your are of course right here, but you miss one important part, because you limit it to direct reflection and direct invokedynamic. Let me make an example: > class Foo {} > Foo.metaClass.bar = {throw new Exception("buh")} > def foo = new Foo() > foo.bar() This code adds a method bar to the class Foo. To show the involved trace I made it throw an exception. We can assume, that I for example call Class#forName(String) here or something similar. The first call is done using reflection and the trace to the caller (where the exception is thrown) looks like this: > at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) > at > sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57) > at > sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) > at java.lang.reflect.Constructor.newInstance(Constructor.java:399) > at > org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:77) > at > org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:102) > at > org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57) > at > org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:182) > at > org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:190) > at test$_run_closure1.doCall(test.groovy:1166) As I understand the new implementation the first 4 frames would be ignored, but that still leaves 5 more in the way here. An if you think just doing this with indy will solve the problem... no: > at > java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L2(MethodHandleImpl.java:1130) > at > org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:212) > at test$_run_closure1.doCall(test.groovy:1166) since I need the dynamic types for a first call, I have one additional frame in here, which will be in the way and give me the wrong class loader. With our callsite caching, if we look not on the first call and say we call a method bar statically defined in Foo, the trace to the caller would look like this: > at Foo.bar(test.groovy:1167) > at Foo$bar.call(Unknown Source) > at test$_run_closure1.doCall(test.groovy:1171) the unknown source here is the runtime generated class. The defining loader of that class is a child of the defining loader of the caller (here test). So this can work... sometimes. For indy, there will be a java.lang.invoke.MethodHandleImpl$GuardWithCatch.invoke_L1 in between, so I assume it will work there. But the first call will fail in both cases. And for Groovy 1.0 it looks even worse. Of course we have to do tricks to get around the limitations. In the past we could for example "replace" the method. Instead of using Class#forName(String) directly we have our own Class#forName, which then calls the bigger variant where I can give in a ClassLoader. We do that for example for ResourceBundle#getBundle(String) But with the new logic I see no other way, then to throw an exception and walk the trace. bye Jochen -- Jochen "blackdrag" Theodorou - Groovy Project Tech Lead blog: http://blackdragsview.blogspot.com/ german groovy discussion newsgroup: de.comp.lang.misc For Groovy programming sources visit http://groovy-lang.org _______________________________________________ mlvm-dev mailing list mlvm-dev@openjdk.java.net http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev