Default methods, mixin and invokeSpecial on JVM
See original GitHub issueclass A { def m = 1 }
class B extends A { override def m = 2 }
trait T extends A
class C extends B with T {
override def m = super[T].m // should invoke A.m currently invokes B.m
}
https://github.com/scala/scala-dev/issues/143#issuecomment-232446342 I have a fix in mind, but I will not have time to try it out before going for vacation. Making a note for myself to come back to it in September.
Issue Analytics
- State:
- Created 7 years ago
- Comments:9 (8 by maintainers)
Top Results From Across the Web
Super calls to default interface methods are incorrectly ...
The super call to the default method in IAngerable looks like this: INVOKESPECIAL net/minecraft/entity/IAngerable.
Read more >How to explicitly invoke default method from a dynamic Proxy?
But how do I explicitly invoke the default method using reflection for example on a proxy? Example: interface ExampleMixin { String getText(); ...
Read more >Chapter 6. The Java Virtual Machine Instruction Set
A Java Virtual Machine instruction consists of an opcode specifying the operation to be performed, followed by zero or more operands embodying values...
Read more >Java Interface Default Methods. What? - 10Pines | Blog
In my last post I've presented both traits and mixins, with the promise of identifying the Java 8 Interface Default Methods.
Read more >Decompiling Traits with Scala 2.11 and 2.12 -
Scala 2.12 (currently at preview stage M4) takes advantage of Java 8 Default Methods to generate optimized JVM byte code for traits.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
ping @lrytz @adriaanm. Just had a long meeting with @odersky, considering the options here. Note that this bug also affects 2.11.8. Giving a proper fix for this bug would change the behavior of already existing code. If existing projects rely on current behavior, bug created because of this change could be very hard to track and may require the code to be rewritten.
We’ve decided, that at least for dotty we would prefer to warn for cases that may misbehave. We have played with HotSpot and reread the spec several times, and decided to:
super[X].foo
, where:C
;foo
;foo
from a class.super[C]
syntax where C is a superclass of this trait. Calling othersuper[mixin]
is allowed unless it’s contradicts previous rule. Callingsuper[<empty>]
is also allowed but means that runtime virtual dispatch would be used.Depending on frequency of those warning we may decide not to implement the scheme
2
that I’ve proposed above, and instead simply reject the code that would require it.Two options:
Just before the phase
ExpandPrivate
move the original body to a method with a name mangled making it globally unique. Similar to how it is done byExpandPrivate
now. The very same phase will rewrite super calls to call those uniquely named methods.The major disadvantage would be increase in size of stack traces. AFAIK, unlike .NET, HotSpot does not expose a way to hide those entries from stack. I would also expect a minor increase in size of generated bytecode.
When compiling class containing super-call(C in your example) create a
@static val
that delegates to reflection in standard library to find the specific target. Compile the super-call itself to an invokeDynamic that evaluates to aConstantCallSite
that points to method that was found using reflection. This one can be benchmarked before implementing it in compiler.If this one works right and is fast, I would prefer it, as 90% of it can be implemented at library side and I’d prefer to start moving more such magic to library. This logic is complex, it will have bugs. If it is entirely implemented on library side, it can be fixed by a library bump without need for recompilation.