forked from scala/scala3
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
backend: Emit calls using the correct receiver
This is a port of scala/scala@765eb29: When emitting a virtual call, the receiver in the bytecode cannot just be the method's owner (the class in which it is declared), because that class may not be accessible at the callsite. Instead we use the type of the receiver. This was basically done to fix - aladdin bug 455 (9954eaf) - SI-1430 (0bea2ab) - basically the same bug, slightly different - SI-4283 (8707c9e) - the same for field reads In Dotty, we rarely encountered this issue because under separate compilation, we see the bridge symbols generated by javac and use their owner as the receiver, but under joint compilation of .java and .scala sources this doesn't happen, in particular this commit fixes scala#6546. It also means that we should now be able to stop creating symbols in the ClassfileParser for Java bridges, this would make joint and separate compilation more similar and thus should reduce the number of bugs which appear in one but not the other as discussed in scala#6266. After this commit, some more changes are necessary to get the updated backend to work correctly with dotty, these are implemented in the later commits of this PR. Co-Authored-By: Lukas Rytz <[email protected]>
- Loading branch information
Showing
11 changed files
with
422 additions
and
159 deletions.
There are no files selected for viewing
296 changes: 145 additions & 151 deletions
296
compiler/src/dotty/tools/backend/jvm/BCodeBodyBuilder.scala
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package pkg; | ||
class P { | ||
public void foo() { | ||
} | ||
} | ||
|
||
public class A extends P { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
object B { | ||
def main(args: Array[String]): Unit = { | ||
val a = new pkg.A | ||
a.foo() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
trait T { override def clone(): Object = "hi" } | ||
trait U extends T | ||
class C1 extends U with Cloneable { | ||
// C1 gets a forwarder for clone that invokes T.clone. this is needed because JVM method | ||
// resolution always prefers class members, so it would resolve to Object.clone, even if | ||
// C1 is a subtype of the interface T which has an overriding default method for clone. | ||
|
||
// invokeinterface T.clone | ||
def f1 = (this: T).clone() | ||
|
||
// cannot invokeinterface U.clone (NoSuchMethodError). Object.clone would work here, but | ||
// not in the example in C2 (illegal access to protected). T.clone works in all cases and | ||
// resolves correctly. | ||
def f2 = (this: U).clone() | ||
|
||
// invokevirtual C1.clone() | ||
def f3 = (this: C1).clone() | ||
} | ||
|
||
class C2 { | ||
def f1(t: T) = t.clone() // invokeinterface T.clone | ||
def f2(t: U) = t.clone() // invokeinterface T.clone -- Object.clone would be illegal (protected, explained in C1) | ||
def f3(t: C1) = t.clone() // invokevirtual C1.clone -- Object.clone would be illegal | ||
} | ||
|
||
object Test { | ||
def main(arg: Array[String]): Unit = { | ||
val r = new StringBuffer() | ||
val c1 = new C1 | ||
r.append(c1.f1) | ||
r.append(c1.f2) | ||
r.append(c1.f3) | ||
val t = new T { } | ||
val u = new U { } | ||
val c2 = new C2 | ||
r.append(c2.f1(t)) | ||
r.append(c2.f1(u)) | ||
r.append(c2.f1(c1)) | ||
r.append(c2.f2(u)) | ||
r.append(c2.f2(c1)) | ||
r.append(c2.f3(c1)) | ||
r.toString | ||
} | ||
} | ||
|
Oops, something went wrong.