diff options
author | Paul Phillips <paulp@improving.org> | 2011-06-23 00:08:33 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-06-23 00:08:33 +0000 |
commit | dbf4bf263ad6e809330a1720c2757f6e62b2bf42 (patch) | |
tree | 5532635de743ec8de5723b039b41b8c7ee3168c2 /src/compiler | |
parent | 444ab5548134b4ad69809285a2ddc30791bef361 (diff) | |
download | scala-dbf4bf263ad6e809330a1720c2757f6e62b2bf42.tar.gz scala-dbf4bf263ad6e809330a1720c2757f6e62b2bf42.tar.bz2 scala-dbf4bf263ad6e809330a1720c2757f6e62b2bf42.zip |
Noticed while working on getClass that most of the
implementations for $hash$hash can be inlined directly, with this kind
of beautiful change:
// source
def hash(x1: Int, x2: Int) = x1.## + x2.##
// before
0: getstatic #11; //Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
3: iload_1
4: invokevirtual #27; //Method scala/runtime/ScalaRunTime$.hash:(I)I
7: getstatic #11; //Field scala/runtime/ScalaRunTime$.MODULE$:Lscala/runtime/ScalaRunTime$;
10: iload_2
11: invokevirtual #27; //Method scala/runtime/ScalaRunTime$.hash:(I)I
14: iadd
15: ireturn
// after
0: iload_1
1: iload_2
2: iadd
3: ireturn
No review.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 34 |
1 files changed, 20 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 2500c84f98..c86a7b5867 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -99,6 +99,15 @@ abstract class Erasure extends AddInterfaces } } + // convert a numeric with a toXXX method + def numericConversion(tree: Tree, numericSym: Symbol): Tree = { + val mname = newTermName("to" + numericSym.name) + val conversion = tree.tpe member mname + + assert(conversion != NoSymbol, tree + " => " + numericSym) + atPos(tree.pos)(Apply(Select(tree, conversion), Nil)) + } + private def unboundedGenericArrayLevel(tp: Type): Int = tp match { case GenericArray(level, core) if !(core <:< AnyRefClass.tpe) => level case _ => 0 @@ -1021,12 +1030,14 @@ abstract class Erasure extends AddInterfaces // erasure the ScalaRunTime.hash overload goes from Unit => Int to BoxedUnit => Int. // This must be because some earlier transformation is being skipped on ##, but so // far I don't know what. For null we now define null.## == 0. - val arg = qual.tpe.typeSymbolDirect match { - case UnitClass => BLOCK(qual, REF(BoxedUnit_UNIT)) // ({ expr; UNIT }).## - case NullClass => LIT(0) // (null: Object).## - case _ => qual + qual.tpe.typeSymbol match { + case UnitClass | NullClass => LIT(0) + case IntClass => qual + case s @ (ShortClass | ByteClass | CharClass) => numericConversion(qual, s) + case BooleanClass => If(qual, LIT(true.##), LIT(false.##)) + case _ => + Apply(gen.mkAttributedRef(scalaRuntimeHash), List(qual)) } - Apply(gen.mkAttributedRef(scalaRuntimeHash), List(arg)) } // Rewrite 5.getClass to ScalaRunTime.anyValClass(5) else if (isValueClass(qual.tpe.typeSymbol)) @@ -1038,16 +1049,11 @@ abstract class Erasure extends AddInterfaces if (fn.symbol == Any_asInstanceOf) (fn: @unchecked) match { case TypeApply(Select(qual, _), List(targ)) => - if (qual.tpe <:< targ.tpe) { + if (qual.tpe <:< targ.tpe) atPos(tree.pos) { Typed(qual, TypeTree(targ.tpe)) } - } else if (isNumericValueClass(qual.tpe.typeSymbol) && - isNumericValueClass(targ.tpe.typeSymbol)) { - // convert numeric type casts - val cname = newTermName("to" + targ.tpe.typeSymbol.name) - val csym = qual.tpe.member(cname) - assert(csym != NoSymbol) - atPos(tree.pos) { Apply(Select(qual, csym), List()) } - } else + else if (isNumericValueClass(qual.tpe.typeSymbol) && isNumericValueClass(targ.tpe.typeSymbol)) + atPos(tree.pos)(numericConversion(qual, targ.tpe.typeSymbol)) + else tree } // todo: also handle the case where the singleton type is buried in a compound |