diff options
Diffstat (limited to 'sources/scalac')
-rw-r--r-- | sources/scalac/symtab/Definitions.java | 8 | ||||
-rw-r--r-- | sources/scalac/transformer/TypesAsValuesPhase.java | 45 | ||||
-rw-r--r-- | sources/scalac/util/Names.java | 1 |
3 files changed, 51 insertions, 3 deletions
diff --git a/sources/scalac/symtab/Definitions.java b/sources/scalac/symtab/Definitions.java index 6dda72353e..8f306ab4ac 100644 --- a/sources/scalac/symtab/Definitions.java +++ b/sources/scalac/symtab/Definitions.java @@ -679,6 +679,14 @@ public class Definitions { return TYPECONSTRUCTOR_FUNCTIONOUTER; } + private Symbol SCALACLASSTYPE_WEAKISINSTANCE; + public Symbol SCALACLASSTYPE_WEAKISINSTANCE() { + if (SCALACLASSTYPE_WEAKISINSTANCE == null) + SCALACLASSTYPE_WEAKISINSTANCE = + loadTerm(SCALACLASSTYPE_CLASS, Names.weakIsInstance); + return SCALACLASSTYPE_WEAKISINSTANCE; + } + private Symbol SCALACLASSTYPE_SETPARENTS; public Symbol SCALACLASSTYPE_SETPARENTS() { if (SCALACLASSTYPE_SETPARENTS == null) diff --git a/sources/scalac/transformer/TypesAsValuesPhase.java b/sources/scalac/transformer/TypesAsValuesPhase.java index b5dc28a0c0..e3ec60af48 100644 --- a/sources/scalac/transformer/TypesAsValuesPhase.java +++ b/sources/scalac/transformer/TypesAsValuesPhase.java @@ -329,7 +329,7 @@ public class TypesAsValuesPhase extends Phase { transformer.apply(unit); } - private class TV_Transformer extends GenTransformer { + private class TV_Transformer extends TV_MiniTransformer { private Symbol currentOwner; public TV_Transformer(Global global) { @@ -736,8 +736,29 @@ public class TypesAsValuesPhase extends Phase { */ private Tree genInstanceTest(int pos, Tree expr, Type tp) { Tree tpVal = typeAsValue(pos, tp, currentOwner, EENV); - Tree fun = gen.Select(pos, tpVal, defs.TYPE_ISINSTANCE()); - return gen.mkApply_V(pos, fun, new Tree[] { expr }); + + if (isKnowClassType(tp) && isLocalIdent(expr)) { + Symbol sym = expr.symbol(); + Tree cheapTest = + gen.mkIsInstanceOf(pos, gen.mkLocalRef(pos, sym), tp, true); + Symbol weakIsInst = defs.SCALACLASSTYPE_WEAKISINSTANCE(); + Tree scalaTpVal = gen.mkAsInstanceOf(pos, + tpVal, + defs.SCALACLASSTYPE_TYPE(), + true); + Tree expensiveTest = + gen.mkApply_V(pos, + gen.Select(pos, scalaTpVal, weakIsInst), + new Tree[] { expr }); + return gen.mkApply_V(pos, + gen.Select(pos, + cheapTest, + defs.BOOLEAN_AND()), + new Tree[] { expensiveTest }); + } else { + Tree fun = gen.Select(pos, tpVal, defs.TYPE_ISINSTANCE()); + return gen.mkApply_V(pos, fun, new Tree[] { expr }); + } } /** @@ -783,6 +804,24 @@ public class TypesAsValuesPhase extends Phase { return false; } + private boolean isKnowClassType(Type tp) { + switch (tp) { + case TypeRef(_, Symbol sym, _): + return (sym != defs.ARRAY_CLASS) && !sym.isParameter(); + default: + return false; + } + } + + private boolean isLocalIdent(Tree tree) { + switch (tree) { + case Ident(_): + return tree.symbol().isLocal(); + default: + return false; + } + } + /** * Transform a type into a tree representing it. */ diff --git a/sources/scalac/util/Names.java b/sources/scalac/util/Names.java index 18013be172..0fda2848fe 100644 --- a/sources/scalac/util/Names.java +++ b/sources/scalac/util/Names.java @@ -222,6 +222,7 @@ public class Names { public static final Name update = Name.fromString("update"); public static final Name view = Name.fromString("view"); public static final Name wait = Name.fromString("wait"); + public static final Name weakIsInstance = Name.fromString("weakIsInstance"); public static final Name xml = Name.fromString("xml"); |