@@ -1731,64 +1731,44 @@ private class FunctionEmitter private (
1731
1731
val sourceTpe = tree.expr.tpe
1732
1732
val targetTpe = tree.tpe
1733
1733
1734
- if (isSubtype( sourceTpe, targetTpe)(isSubclass(_, _)) ) {
1735
- // Common case where no cast is necessary
1736
- genTreeAuto (tree.expr)
1737
- sourceTpe
1734
+ if (sourceTpe == NothingType ) {
1735
+ // We cannot call transformType for NothingType, so we have to handle this case separately.
1736
+ genTree (tree.expr, NothingType )
1737
+ NothingType
1738
1738
} else {
1739
- genTree(tree.expr, AnyType )
1739
+ // By IR checker rules, targetTpe is none of NothingType, NullType, NoType or RecordType
1740
1740
1741
- markPosition(tree)
1741
+ val sourceWasmType = TypeTransformer .transformType(sourceTpe)(ctx)
1742
+ val targetWasmType = TypeTransformer .transformType(targetTpe)(ctx)
1742
1743
1743
- def genAsPrimType (targetTpe : PrimType ): Unit = {
1744
- // TODO We could do something better for things like double.asInstanceOf[int]
1745
- genUnbox(targetTpe)(tree.pos)
1746
- }
1744
+ if (sourceWasmType == targetWasmType) {
1745
+ /* Common case where no cast is necessary at the Wasm level.
1746
+ * Note that this is not *obviously* correct. It is only correct
1747
+ * because, under our choices of representation and type translation
1748
+ * rules, there is no pair `(sourceTpe, targetTpe)` for which the Wasm
1749
+ * types are equal but a valid cast would require a *conversion*.
1750
+ */
1751
+ genTreeAuto(tree.expr)
1752
+ } else {
1753
+ genTree(tree.expr, AnyType )
1747
1754
1748
- targetTpe match {
1749
- case targetTpe : PrimType =>
1750
- genAsPrimType(targetTpe)
1755
+ markPosition(tree)
1751
1756
1752
- case AnyType =>
1753
- ()
1757
+ targetTpe match {
1758
+ case targetTpe : PrimType =>
1759
+ // TODO Opt: We could do something better for things like double.asInstanceOf[int]
1760
+ genUnbox(targetTpe)(tree.pos)
1754
1761
1755
- case ClassType (targetClassName) =>
1756
- val info = ctx.getClassInfo(targetClassName)
1757
- if (info.kind == ClassKind .HijackedClass ) {
1758
- BoxedClassToPrimType (targetClassName) match {
1759
- case UndefType | StringType =>
1760
- ()
1761
- case primType : PrimTypeWithRef =>
1762
- primType match {
1763
- case CharType =>
1764
- val structTypeName = genTypeID.forClass(SpecialNames .CharBoxClass )
1765
- instrs += wa.RefCast (watpe.RefType .nullable(structTypeName))
1766
- case LongType =>
1767
- val structTypeName = genTypeID.forClass(SpecialNames .LongBoxClass )
1768
- instrs += wa.RefCast (watpe.RefType .nullable(structTypeName))
1769
- case NoType | NothingType | NullType =>
1770
- throw new AssertionError (s " Unexpected prim type $primType for $targetClassName" )
1771
- case _ =>
1772
- instrs += wa.Call (genFunctionID.unboxOrNull(primType.primRef))
1773
- }
1762
+ case _ =>
1763
+ targetWasmType match {
1764
+ case watpe.RefType (true , watpe.HeapType .Any ) =>
1765
+ () // nothing to do
1766
+ case targetWasmType : watpe.RefType =>
1767
+ instrs += wa.RefCast (targetWasmType)
1768
+ case _ =>
1769
+ throw new AssertionError (s " Unexpected type in AsInstanceOf: $targetTpe" )
1774
1770
}
1775
- } else if (info.isAncestorOfHijackedClass) {
1776
- // Nothing to do; the translation is `anyref`
1777
- ()
1778
- } else if (info.kind.isClass) {
1779
- instrs += wa.RefCast (
1780
- watpe.RefType .nullable(genTypeID.forClass(targetClassName))
1781
- )
1782
- } else if (info.isInterface) {
1783
- instrs += wa.RefCast (watpe.RefType .nullable(genTypeID.ObjectStruct ))
1784
- }
1785
-
1786
- case ArrayType (arrayTypeRef) =>
1787
- val structTypeName = genTypeID.forArrayClass(arrayTypeRef)
1788
- instrs += wa.RefCast (watpe.RefType .nullable(structTypeName))
1789
-
1790
- case targetTpe : RecordType =>
1791
- throw new AssertionError (s " Illegal type in AsInstanceOf: $targetTpe" )
1771
+ }
1792
1772
}
1793
1773
1794
1774
targetTpe
@@ -1842,9 +1822,6 @@ private class FunctionEmitter private (
1842
1822
}
1843
1823
}
1844
1824
1845
- private def isSubclass (subClass : ClassName , superClass : ClassName ): Boolean =
1846
- ctx.getClassInfo(subClass).ancestors.contains(superClass)
1847
-
1848
1825
private def genGetClass (tree : GetClass ): Type = {
1849
1826
/* Unlike in `genApply` or `genStringConcat`, here we make no effort to
1850
1827
* optimize known-primitive receivers. In practice, such cases would be
@@ -2282,25 +2259,15 @@ private class FunctionEmitter private (
2282
2259
private def genLoadJSModule (tree : LoadJSModule ): Type = {
2283
2260
markPosition(tree)
2284
2261
2285
- val info = ctx.getClassInfo(tree.className)
2286
-
2287
- info.kind match {
2288
- case ClassKind .NativeJSModuleClass =>
2289
- val jsNativeLoadSpec = info.jsNativeLoadSpec.getOrElse {
2290
- throw new AssertionError (s " Found $tree for class without jsNativeLoadSpec at ${tree.pos}" )
2291
- }
2292
- genLoadJSFromSpec(instrs, jsNativeLoadSpec)(ctx)
2293
- AnyType
2294
-
2295
- case ClassKind .JSModuleClass =>
2262
+ ctx.getClassInfo(tree.className).jsNativeLoadSpec match {
2263
+ case Some (loadSpec) =>
2264
+ genLoadJSFromSpec(instrs, loadSpec)(ctx)
2265
+ case None =>
2266
+ // This is a non-native JS module
2296
2267
instrs += wa.Call (genFunctionID.loadModule(tree.className))
2297
- AnyType
2298
-
2299
- case _ =>
2300
- throw new AssertionError (
2301
- s " Invalid LoadJSModule for class ${tree.className.nameString} of kind ${info.kind}"
2302
- )
2303
2268
}
2269
+
2270
+ AnyType
2304
2271
}
2305
2272
2306
2273
private def genSelectJSNativeMember (tree : SelectJSNativeMember ): Type = {
0 commit comments