Hey folks, lately I've started extending Dynalink with support for honoring the Lookup object passed to the bootstrap methods. Just generally making sure it's propagated through the framework is easy enough, and I'm also taking care to ensure that language environments that don't need this (i.e. always use only publicLookup() and/or only care about linking to public methods) don't get worse linking performance than what's already there.
However, actually making the changes in BeanLinker for POJO linking prove to be quite daunting… You would think I should just rely on JLS to resolve the issues, but unfortunately there's one really big distinction between access as described in JLS, and access as it happens with dynamic linking: with JLS, your callee is a compile-type declared type; with dynamic linking, it's always a run-time concrete type. How's that problematic? Consider these examples: Example 1: class C { private f() { } } class D extends C { } Let's assume class C has an invokedynamic call site for "obj.f()", and ends up getting an instance of D. Should it be able to invoke C.f()? I think yes. Okay, but how about this: class C { private f() { } } class D extends C { private f() { } } If C should dynamically link its call site for method "f()" and got an instance of D, what should it invoke? Should it invoke C.f(), or should it throw an error because D.f() exists but is not visible to it? Okay, how about this: class C { private f() { } } class D extends C { public f() { } } Intuitively, I'd want C to invoke D.f() in this situation if it'd have a call site for f() and got an instance of D as a callee. You might ask, wouldn't it break encapsulation somewhere? I think not, because if the code of C is invoking something dynamically, it will not have an expectation of that something being an instance of C, so the code better not rely on it always being C.f() that is invoked. Fair enough? Oh wait, but what if the dynamic call site actually specifies C.class as the type of the 0th argument? Then you could argue the intent of the program is to invoke C.f()? But why would a class invoke its own private member using invokedynamic? It probably wouldn't, so I most likely shouldn't care about the declared type of the receiver at the call site. I'm putting these up for debate, as I'm not sure myself either what'd be the correct approach here. Here's another example: Example 2: (I'm using p1 and p2 as package prefixes) public class p1.Base { f() { } } public class p2.Derived { } class p1.Caller { ... } Imagine p1.Caller has a dynamic call site for f(), and it gets an instance of p2.Derived as the callee. Should it be able to link to p1.Base.f() as an invocation of f() on p2.Derived? Intuition tells me that, yes, it should -- after all, the method is declared in the p1 package even if the p2.Derived isn't. Again, we don't rely on declared types; the call site in p1.Caller probably says java.lang.Object as the 0th argument. How about if p2.Derived also declares a package-private method f()? public class p1.Base { f() { } } public class p2.Derived { f() { } } class p1.Caller { ... } Should p1.Caller's f()-invoking dynamic call site now invoke p1.Base.f() when we supply it a p2.Derived instance as the callee, or should it throw an error claiming p2.Derived.f() is not visible to it? I don't know the correct answer. I lean towards invoking p1.Base.f(), but this is not nearly clear cut. Would it make a difference if the call site in p1.Caller declared its 0th argument to be p1.Base? (Again, why would any call site with such a specific knowledge of the target be emitted using invokedynamic?) Similar issues apply to protected access. Opinions and discussion welcome. Thanks, Attila. -- You received this message because you are subscribed to the Google Groups "JVM Languages" group. To post to this group, send email to jvm-languages@googlegroups.com. To unsubscribe from this group, send email to jvm-languages+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/jvm-languages?hl=en.