Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit1501c94

Browse files
authored
Merge pull request#5210 from tanishiking/asinstanceof-linktimeif
Removes spurious js.AsInstanceOf around the js.LinkTimeIf
2 parents849495b +9bb267c commit1501c94

File tree

3 files changed

+115
-1
lines changed

3 files changed

+115
-1
lines changed

‎compiler/src/main/scala/org/scalajs/nscplugin/GenJSCode.scala

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3207,7 +3207,30 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
32073207
caseObject_isInstanceOf=>
32083208
genIsAsInstanceOf(obj, targs, cast=false)
32093209
caseObject_asInstanceOf=>
3210-
genIsAsInstanceOf(obj, targs, cast=true)
3210+
valtargetTpe= targs.head.tpe
3211+
objmatch {
3212+
/* This is an optimization for `linkTimeIf(cond)(thenp)(elsep).asInstanceOf[T]`.
3213+
* If both `thenp` and `elsep` are subtypes of `T`, the `asInstanceOf`
3214+
* is redundant and can be removed. The optimizer already routinely performs
3215+
* this optimization. However, that comes too late for the module instance
3216+
* field alias analysis performed by `IncOptimizer`. In that case, while the
3217+
* desugarer removes the `LinkTimeIf`, the extra `AsInstanceOf` prevents
3218+
* aliasing the field. Removing the cast ahead of time in the compiler allows
3219+
* field aliases to be recognized in the presence of `LinkTimeIf`s.
3220+
*/
3221+
caseApply(fun,List(cond, thenp, elsep))
3222+
if fun.symbol== jsDefinitions.LinkingInfo_linkTimeIf&&
3223+
thenp.tpe<:< targetTpe&& elsep.tpe<:< targetTpe=>
3224+
valgenObj= genExpr(obj)match {
3225+
caset: js.LinkTimeIf=> t
3226+
case t=>
3227+
abort("Unexpected tree"+ t+
3228+
" is generated for"+ fun+" at:"+ tree.pos)
3229+
}
3230+
js.LinkTimeIf(genObj.cond, genObj.thenp, genObj.elsep)(toIRType(targetTpe))(genObj.pos)
3231+
case _=>
3232+
genIsAsInstanceOf(obj, targs, cast=true)
3233+
}
32113234
caseObject_synchronized=>
32123235
genSynchronized(obj, args.head, isStat)
32133236
case _=>

‎compiler/src/test/scala/org/scalajs/nscplugin/test/OptimizationTest.scala

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,50 @@ class OptimizationTest extends JSASTTest {
648648
}
649649
}
650650
}
651+
652+
@Test
653+
deflinkTimeIf:Unit= {
654+
/* Make sure the cast in
655+
* `linkTimeIf(cond)(thenp)(elsep).asInstanceOf[T]``
656+
* is optimized away if `thenp` and `elsep` are subtypes of `T`.
657+
*/
658+
"""
659+
import scala.scalajs.js
660+
import scala.scalajs.LinkingInfo._
661+
662+
class LinkTimeIfTest {
663+
import LinkTimeIfTest._
664+
private val impl = linkTimeIf[ArrayImpl](productionMode) {
665+
JSArrayImpl
666+
} {
667+
ScalaArrayImpl
668+
}
669+
def implPattern(): Int = {
670+
impl.length(impl.empty())
671+
}
672+
}
673+
object LinkTimeIfTest {
674+
sealed private abstract class ArrayImpl {
675+
type Repr
676+
def empty(): Repr
677+
def length(v: Repr): Int
678+
}
679+
private object JSArrayImpl extends ArrayImpl {
680+
type Repr = js.Array[AnyRef]
681+
def empty(): Repr = js.Array[AnyRef]()
682+
def length(v: Repr): Int = v.length
683+
}
684+
private object ScalaArrayImpl extends ArrayImpl {
685+
type Repr = Array[AnyRef]
686+
def empty(): Repr = new Array[AnyRef](0)
687+
def length(v: Repr): Int = v.length
688+
}
689+
}
690+
""".
691+
hasNot("linkTimeIf[A](...).asInstanceOf[A]") {
692+
case js.AsInstanceOf(_:js.LinkTimeIf, _)=>
693+
}
694+
}
651695
}
652696

653697
objectOptimizationTest {

‎test-suite/js/src/test/scala/org/scalajs/testsuite/library/LinkTimeIfTest.scala

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,51 @@ class LinkTimeIfTest {
9292
}
9393
assertEquals(pow(2.0,8.0),256.0,0)
9494
}
95+
96+
// This test verifies that the compiler can safely compile surrounding
97+
// implicit asInstanceOf casts to a supertype.
98+
@Testdefsubtyping():Unit= {
99+
traitA {defvalue:Int }
100+
classB(valvalue:Int)extendsA
101+
classC(valvalue:Int)extendsA
102+
103+
valb=newB(1)
104+
valc=newC(2)
105+
106+
valresult1= linkTimeIf[A](productionMode) { b } { c }
107+
assertEquals(if (Platform.isInProductionMode) b.valueelse c.value, result1.value)
108+
109+
valresult2= linkTimeIf[A](productionMode) { c } { b }
110+
assertEquals(if (Platform.isInProductionMode) c.valueelse b.value, result2.value)
111+
}
112+
113+
@TestdefimplPattern():Unit= {
114+
importLinkTimeIfTest._
115+
valimpl= linkTimeIf[ArrayImpl](productionMode) {
116+
JSArrayImpl
117+
} {
118+
ScalaArrayImpl
119+
}
120+
assertEquals(0, impl.length(impl.empty()))
121+
}
122+
}
123+
124+
objectLinkTimeIfTest {
125+
sealedprivateabstractclassArrayImpl {
126+
typeRepr
127+
defempty():Repr
128+
deflength(v:Repr):Int
129+
}
130+
131+
privateobjectJSArrayImplextendsArrayImpl {
132+
typeRepr= js.Array[AnyRef]
133+
defempty():Repr= js.Array[AnyRef]()
134+
deflength(v:Repr):Int= v.length
135+
}
136+
137+
privateobjectScalaArrayImplextendsArrayImpl {
138+
typeRepr=Array[AnyRef]
139+
defempty():Repr=newArray[AnyRef](0)
140+
deflength(v:Repr):Int= v.length
141+
}
95142
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp