diff options
Diffstat (limited to 'src')
18 files changed, 110 insertions, 246 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 092c478bef..1cc3d580d9 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -172,11 +172,27 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val AnyValCompanionClass = getClass("scala.AnyValCompanion") setFlag (SEALED | ABSTRACT | TRAIT) // bottom types - lazy val NullClass = newClass(ScalaPackageClass, tpnme.Null, anyrefparam) setFlag (ABSTRACT | TRAIT | FINAL) - lazy val NothingClass = newClass(ScalaPackageClass, tpnme.Nothing, anyparam) setFlag (ABSTRACT | TRAIT | FINAL) lazy val RuntimeNothingClass = getClass(ClassfileConstants.SCALA_NOTHING) lazy val RuntimeNullClass = getClass(ClassfileConstants.SCALA_NULL) + sealed abstract class BottomClassSymbol(name: TypeName, parent: Symbol) extends ClassSymbol(ScalaPackageClass, NoPosition, name) { + locally { + this setFlag ABSTRACT | TRAIT | FINAL + this setInfo ClassInfoType(List(parent.tpe), new Scope, this) + owner.info.decls enter this + } + final override def isBottomClass = true + } + final object NothingClass extends BottomClassSymbol(tpnme.Nothing, AnyClass) { + override def isSubClass(that: Symbol) = true + } + final object NullClass extends BottomClassSymbol(tpnme.Null, AnyRefClass) { + override def isSubClass(that: Symbol) = ( + (that eq AnyClass) + || (that ne NothingClass) && (that isSubClass ObjectClass) + ) + } + // exceptions and other throwables lazy val ClassCastExceptionClass = getClass("java.lang.ClassCastException") lazy val IndexOutOfBoundsExceptionClass = getClass(sn.IOOBException) @@ -351,12 +367,6 @@ trait Definitions extends reflect.api.StandardDefinitions { lazy val ScalaSignatureAnnotation = getClass("scala.reflect.ScalaSignature") lazy val ScalaLongSignatureAnnotation = getClass("scala.reflect.ScalaLongSignature") - // invoke dynamic support - lazy val LinkageModule = getModule("java.dyn.Linkage") - lazy val Linkage_invalidateCallerClass = getMember(LinkageModule, "invalidateCallerClass") - lazy val DynamicDispatchClass = getModule("scala.runtime.DynamicDispatch") - lazy val DynamicDispatch_DontSetTarget = getMember(DynamicDispatchClass, "DontSetTarget") - // Option classes lazy val OptionClass: Symbol = getClass("scala.Option") lazy val SomeClass: Symbol = getClass("scala.Some") diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index 65b60bfa39..058108c285 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -334,6 +334,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isTerm = false // to be overridden def isType = false // to be overridden def isClass = false // to be overridden + def isBottomClass = false // to be overridden def isAliasType = false // to be overridden def isAbstractType = false // to be overridden private[scala] def isSkolem = false // to be overridden @@ -951,6 +952,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => } def hasRawInfo: Boolean = infos ne null + def hasCompleteInfo = hasRawInfo && rawInfo.isComplete /** Return info without checking for initialization or completing */ def rawInfo: Type = { @@ -1236,17 +1238,15 @@ trait Symbols extends api.Symbols { self: SymbolTable => owner == that || owner != NoSymbol && (owner isNestedIn that) /** Is this class symbol a subclass of that symbol? */ - final def isNonBottomSubClass(that: Symbol): Boolean = - this == that || this.isError || that.isError || + final def isNonBottomSubClass(that: Symbol): Boolean = ( + (this eq that) || this.isError || that.isError || info.baseTypeIndex(that) >= 0 - - final def isSubClass(that: Symbol): Boolean = ( - isNonBottomSubClass(that) || - this == NothingClass || - this == NullClass && - (that == AnyClass || - that != NothingClass && (that isSubClass ObjectClass)) ) + + /** Overridden in NullClass and NothingClass for custom behavior. + */ + def isSubClass(that: Symbol) = isNonBottomSubClass(that) + final def isNumericSubClass(that: Symbol): Boolean = definitions.isNumericSubClass(this, that) @@ -2425,6 +2425,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => unlock() validTo = currentPeriod } + override def isSubClass(that: Symbol) = false override def filter(cond: Symbol => Boolean) = this override def defString: String = toString override def locationString: String = "" diff --git a/src/compiler/scala/reflect/internal/Types.scala b/src/compiler/scala/reflect/internal/Types.scala index a9dded3cd1..320fb949ff 100644 --- a/src/compiler/scala/reflect/internal/Types.scala +++ b/src/compiler/scala/reflect/internal/Types.scala @@ -3063,8 +3063,7 @@ A type's typeSymbol should never be inspected directly. case TypeRef(pre, sym, args) if (variance != 0) && (occurCount isDefinedAt sym) => val repl = if (variance == 1) dropSingletonType(tp1.bounds.hi) else tp1.bounds.lo //println("eliminate "+sym+"/"+repl+"/"+occurCount(sym)+"/"+(tparams exists (repl.contains)))//DEBUG - if (repl.typeSymbol != NothingClass && repl.typeSymbol != NullClass && - occurCount(sym) == 1 && !(tparams exists (repl.contains))) + if (!repl.typeSymbol.isBottomClass && occurCount(sym) == 1 && !(tparams exists (repl.contains))) repl else tp1 case _ => diff --git a/src/compiler/scala/reflect/internal/transform/Erasure.scala b/src/compiler/scala/reflect/internal/transform/Erasure.scala index 9648befb49..c8cb6febfa 100644 --- a/src/compiler/scala/reflect/internal/transform/Erasure.scala +++ b/src/compiler/scala/reflect/internal/transform/Erasure.scala @@ -75,7 +75,7 @@ trait Erasure { case TypeRef(pre, sym, args) => if (sym == ArrayClass) if (unboundedGenericArrayLevel(tp) == 1) ObjectClass.tpe - else if (args.head.typeSymbol == NothingClass || args.head.typeSymbol == NullClass) arrayType(ObjectClass.tpe) + else if (args.head.typeSymbol.isBottomClass) arrayType(ObjectClass.tpe) else typeRef(apply(pre), sym, args map this) else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass || sym == NotNullClass) erasedTypeRef(ObjectClass) else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass) diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala index 90e387d384..e26a0d59e8 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala @@ -24,7 +24,7 @@ abstract class GenICode extends SubComponent { import icodes._ import icodes.opcodes._ import definitions.{ - ArrayClass, ObjectClass, ThrowableClass, StringClass, StringModule, NothingClass, NullClass, AnyRefClass, + ArrayClass, ObjectClass, ThrowableClass, StringClass, StringModule, AnyRefClass, Object_equals, Object_isInstanceOf, Object_asInstanceOf, ScalaRunTimeModule, BoxedNumberClass, BoxedCharacterClass, getMember @@ -923,12 +923,13 @@ abstract class GenICode extends SubComponent { } case ApplyDynamic(qual, args) => - assert(!forMSIL) - ctx.clazz.bootstrapClass = Some("scala.runtime.DynamicDispatch") - val ctx1 = genLoad(qual, ctx, ObjectReference) - genLoadArguments(args, tree.symbol.info.paramTypes, ctx1) - ctx1.bb.emit(CALL_METHOD(tree.symbol, InvokeDynamic), tree.pos) - ctx1 + assert(!forMSIL, tree) + // TODO - this is where we'd catch dynamic applies for invokedynamic. + sys.error("No invokedynamic support yet.") + // val ctx1 = genLoad(qual, ctx, ObjectReference) + // genLoadArguments(args, tree.symbol.info.paramTypes, ctx1) + // ctx1.bb.emit(CALL_METHOD(tree.symbol, InvokeDynamic), tree.pos) + // ctx1 case This(qual) => assert(tree.symbol == ctx.clazz.symbol || tree.symbol.isModuleClass, diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 5aa76fad83..2f43d43bdd 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -106,7 +106,6 @@ trait Members { self: ICodes => var fields: List[IField] = Nil var methods: List[IMethod] = Nil var cunit: CompilationUnit = _ - var bootstrapClass: Option[String] = None def addField(f: IField): this.type = { fields = f :: fields; diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala index ba33c425f2..2bcfb9d4a9 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala @@ -616,7 +616,6 @@ trait Opcodes { self: ICodes => /** Returns a string representation of this style. */ override def toString(): String = this match { case Dynamic => "dynamic" - case InvokeDynamic => "invoke-dynamic" case Static(false) => "static-class" case Static(true) => "static-instance" case SuperCall(mix) => "super(" + mix + ")" @@ -626,9 +625,6 @@ trait Opcodes { self: ICodes => /** Virtual calls */ case object Dynamic extends InvokeStyle - /** InvokeDynamic a la JSR 292 (experimental). */ - case object InvokeDynamic extends InvokeStyle - /** * Special invoke. Static(true) is used for calls to private * members. diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index 16cba38f9a..5af5b05682 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -321,7 +321,7 @@ abstract class CopyPropagation { out.stack = Unknown :: out.stack.drop(i.consumed) case CALL_METHOD(method, style) => style match { - case Dynamic | InvokeDynamic => + case Dynamic => out = simulateCall(in, method, false) case Static(onInstance) => diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 9d5cc9e0a6..3fe5b83515 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -31,7 +31,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with import icodes._ import icodes.opcodes._ import definitions.{ - NullClass, RuntimeNullClass, NothingClass, RuntimeNothingClass, AnyClass, ObjectClass, ThrowsClass, ThrowableClass, ClassfileAnnotationClass, SerializableClass, StringClass, ClassClass, FunctionClass, DeprecatedAttr, SerializableAttr, SerialVersionUIDAttr, VolatileAttr, @@ -332,8 +331,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with ifaces, c.cunit.source.toString) - if (isStaticModule(c.symbol) || serialVUID != None || isParcelableClass || - clasz.bootstrapClass.isDefined) { + if (isStaticModule(c.symbol) || serialVUID != None || isParcelableClass) { if (isStaticModule(c.symbol)) addModuleInstanceField addStaticInit(jclass, c.lookupStaticCtor) @@ -375,9 +373,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } - if (clasz.bootstrapClass.isDefined) - jclass setBootstrapClass clasz.bootstrapClass.get - clasz.fields foreach genField clasz.methods foreach genMethod @@ -913,8 +908,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with mopt match { case Some(m) => - if (clasz.bootstrapClass.isDefined) legacyEmitBootstrapMethodInstall(clinit) - val oldLastBlock = m.code.blocks.last val lastBlock = m.code.newBlock oldLastBlock.replaceInstruction(oldLastBlock.length - 1, JUMP(lastBlock)) @@ -940,11 +933,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if (isParcelableClass) addCreatorCode(BytecodeGenerator.this, lastBlock) - if (clasz.bootstrapClass.isDefined) { - // emit bootstrap method install - //emitBootstrapMethodInstall(block) - } - lastBlock emit RETURN(UNIT) lastBlock.close @@ -975,28 +963,9 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if (isParcelableClass) legacyAddCreatorCode(BytecodeGenerator.this, clinit) - if (clasz.bootstrapClass.isDefined) - legacyEmitBootstrapMethodInstall(clinit) - clinit.emitRETURN() } - /** Emit code that installs a boostrap method for invoke dynamic. It - * installs the default method, found in scala.runtime.DynamicDispatch. - */ - def legacyEmitBootstrapMethodInstall(jcode: JExtendedCode) { - jcode emitPUSH jclass.getType.asInstanceOf[JReferenceType] - jcode emitPUSH new JObjectType("scala.runtime.DynamicDispatch") - jcode emitPUSH "bootstrapInvokeDynamic" - jcode.emitGETSTATIC("java.dyn.Linkage", "BOOTSTRAP_METHOD_TYPE", MethodTypeType) - jcode.emitDUP - jcode.emitINVOKESTATIC("scala.Console", "println", new JMethodType(JType.VOID, Array(JAVA_LANG_OBJECT))) - jcode.emitINVOKESTATIC("java.dyn.MethodHandles", "findStatic", - new JMethodType(MethodHandleType, Array(JavaLangClassType, JAVA_LANG_STRING, MethodTypeType))) - jcode.emitINVOKESTATIC("java.dyn.Linkage", "registerBootstrapMethod", - new JMethodType(JType.VOID, Array(JavaLangClassType, MethodHandleType))) - } - /** Add a forwarder for method m */ def addForwarder(jclass: JClass, module: Symbol, m: Symbol) { val moduleName = javaName(module) @@ -1197,6 +1166,68 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with } } + def isAccessibleFrom(target: Symbol, site: Symbol): Boolean = { + target.isPublic || target.isProtected && { + (site.enclClass isSubClass target.enclClass) || + (site.enclosingPackage == target.privateWithin) + } + } + + def genCallMethod(call: CALL_METHOD) { + val CALL_METHOD(method, style) = call + val siteSymbol = clasz.symbol + val hostSymbol = call.hostClass + val methodOwner = method.owner + // info calls so that types are up to date; erasure may add lateINTERFACE to traits + hostSymbol.info ; methodOwner.info + + def isInterfaceCall(sym: Symbol) = ( + sym.isInterface + || sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass) + ) + // whether to reference the type of the receiver or + // the type of the method owner (if not an interface!) + val useMethodOwner = ( + style != Dynamic + || !isInterfaceCall(hostSymbol) && isAccessibleFrom(methodOwner, siteSymbol) + || hostSymbol.isBottomClass + ) + val receiver = if (useMethodOwner) methodOwner else hostSymbol + val jowner = javaName(receiver) + val jname = javaName(method) + val jtype = javaType(method).asInstanceOf[JMethodType] + + def emit(invoke: String) { + log("%s %s %s.%s:%s".format(invoke, receiver.accessString, jowner, jname, jtype)) + invoke match { + case "invokeinterface" => jcode.emitINVOKEINTERFACE(jowner, jname, jtype) + case "invokevirtual" => jcode.emitINVOKEVIRTUAL(jowner, jname, jtype) + case "invokespecial" => jcode.emitINVOKESPECIAL(jowner, jname, jtype) + case "invokestatic" => jcode.emitINVOKESTATIC(jowner, jname, jtype) + } + } + def initModule() { + // we initialize the MODULE$ field immediately after the super ctor + if (isStaticModule(siteSymbol) && !isModuleInitialized && + jmethod.getName() == JMethod.INSTANCE_CONSTRUCTOR_NAME && + jname == JMethod.INSTANCE_CONSTRUCTOR_NAME) { + isModuleInitialized = true + jcode.emitALOAD_0() + jcode.emitPUTSTATIC(jclass.getName(), + nme.MODULE_INSTANCE_FIELD.toString, + jclass.getType()) + } + } + + style match { + case Static(true) => emit("invokespecial") + case Static(false) => emit("invokestatic") + case Dynamic if isInterfaceCall(receiver) => emit("invokeinterface") + case Dynamic => emit("invokevirtual") + case SuperCall(_) => emit("invokespecial") ; initModule() + } + } + def genBlock(b: BasicBlock) { labels(b).anchorToNext() @@ -1276,43 +1307,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType) case call @ CALL_METHOD(method, style) => - val owner: String = javaName(method.owner) - // reference the type of the receiver instead of the method owner (if not an interface!) - val dynamicOwner = - if (needsInterfaceCall(call.hostClass)) owner - else javaName(call.hostClass) - val jname = javaName(method) - val jtype = javaType(method).asInstanceOf[JMethodType] - - style match { - case InvokeDynamic => - jcode.emitINVOKEINTERFACE("java.dyn.Dynamic", jname, jtype) - - case Dynamic => - if (needsInterfaceCall(method.owner)) - jcode.emitINVOKEINTERFACE(owner, jname, jtype) - else - jcode.emitINVOKEVIRTUAL(dynamicOwner, jname, jtype) - - case Static(instance) => - if (instance) - jcode.emitINVOKESPECIAL(owner, jname, jtype) - else - jcode.emitINVOKESTATIC(owner, jname, jtype) - - case SuperCall(_) => - jcode.emitINVOKESPECIAL(owner, jname, jtype) - // we initialize the MODULE$ field immediately after the super ctor - if (isStaticModule(clasz.symbol) && !isModuleInitialized && - jmethod.getName() == JMethod.INSTANCE_CONSTRUCTOR_NAME && - jname == JMethod.INSTANCE_CONSTRUCTOR_NAME) { - isModuleInitialized = true - jcode.emitALOAD_0() - jcode.emitPUTSTATIC(jclass.getName(), - nme.MODULE_INSTANCE_FIELD.toString, - jclass.getType()) - } - } + genCallMethod(call) case BOX(kind) => val boxedType = definitions.boxedClass(kind.toType.typeSymbol) @@ -1839,20 +1834,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with ////////////////////// Utilities //////////////////////// - /** Calls to methods in 'sym' need invokeinterface? */ - def needsInterfaceCall(sym: Symbol): Boolean = { - debuglog("checking for interface call: " + sym.fullName) - // the following call to 'info' may cause certain symbols to fail loading - // because we're too late in the compilation chain (aliases to overloaded - // symbols will not be properly resolved, see scala.Range, method - // `super$++` that fails in UnPickler at LazyTypeRefAndAlias.complete - if (sym.isTrait) sym.info // needed so that the type is up to date - // (erasure may add lateINTERFACE to traits) - - sym.isInterface || - (sym.isJavaDefined && sym.isNonBottomSubClass(ClassfileAnnotationClass)) - } - /** Merge adjacent ranges. */ private def mergeEntries(ranges: List[(Int, Int)]): List[(Int, Int)] = (ranges.foldLeft(Nil: List[(Int, Int)]) { (collapsed: List[(Int, Int)], p: (Int, Int)) => (collapsed, p) match { diff --git a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala index 9c34565928..015dc2a7f1 100644 --- a/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala +++ b/src/compiler/scala/tools/nsc/interpreter/CompletionOutput.scala @@ -15,7 +15,7 @@ trait CompletionOutput { val global: Global import global._ - import definitions.{ NothingClass, AnyClass, isTupleTypeOrSubtype, isFunctionType, isRepeatedParamType } + import definitions.{ isTupleTypeOrSubtype, isFunctionType, isRepeatedParamType } /** Reducing fully qualified noise for some common packages. */ diff --git a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala index c97d65c6bc..11d829eadb 100644 --- a/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala +++ b/src/compiler/scala/tools/nsc/matching/ParallelMatching.scala @@ -25,7 +25,7 @@ trait ParallelMatching extends ast.TreeDSL import global.{ typer => _, _ } import definitions.{ - AnyRefClass, NothingClass, IntClass, BooleanClass, SomeClass, OptionClass, + AnyRefClass, IntClass, BooleanClass, SomeClass, OptionClass, getProductArgs, productProj, Object_eq, Any_asInstanceOf } import CODE._ diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala index 1f32355bf7..e62070a239 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTrackers.scala @@ -131,7 +131,7 @@ trait SymbolTrackers { else " (" + Flags.flagsToString(masked) + ")" } def symString(sym: Symbol) = ( - if (settings.debug.value && sym.hasRawInfo && sym.rawInfo.isComplete) { + if (settings.debug.value && sym.hasCompleteInfo) { val s = sym.defString take 240 if (s.length == 240) s + "..." else s } diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index ef1bcdd739..e67ce90cfa 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -1257,7 +1257,7 @@ abstract class ClassfileParser { protected def getScope(flags: Int): Scope = if (isStatic(flags)) staticDefs else instanceDefs - private def setPrivateWithin(sym: Symbol, jflags: Int) { + private def setPrivateWithin(sym: Symbol, jflags: Int) { if ((jflags & (JAVA_ACC_PRIVATE | JAVA_ACC_PROTECTED | JAVA_ACC_PUBLIC)) == 0) // See ticket #1687 for an example of when topLevelClass is NoSymbol: it // apparently occurs when processing v45.3 bytecode. diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 054fb1c036..62ad78c64d 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -1033,8 +1033,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { && qual.isTerm && ((qual.symbol eq null) || !qual.symbol.isTerm || qual.symbol.isValue) && !qtpe.isError - && qtpe.typeSymbol != NullClass - && qtpe.typeSymbol != NothingClass + && !qtpe.typeSymbol.isBottomClass && qtpe != WildcardType && !qual.isInstanceOf[ApplyImplicitView] // don't chain views && context.implicitsEnabled @@ -2190,10 +2189,8 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser { * in an argument closure overlaps with an uninstantiated formal? */ def needsInstantiation(tparams: List[Symbol], formals: List[Type], args: List[Tree]) = { - def isLowerBounded(tparam: Symbol) = { - val losym = tparam.info.bounds.lo.typeSymbol - losym != NothingClass && losym != NullClass - } + def isLowerBounded(tparam: Symbol) = !tparam.info.bounds.lo.typeSymbol.isBottomClass + (formals, args).zipped exists { case (formal, Function(vparams, _)) => (vparams exists (_.tpt.isEmpty)) && diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java index 212058a660..b66bbd8bc0 100644 --- a/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java +++ b/src/fjbg/ch/epfl/lamp/fjbg/JAttributeFactory.java @@ -48,7 +48,6 @@ public class JAttributeFactory { Constructor defaultConstructor) { this.context = context; this.defaultConstructor = defaultConstructor; - registerClass("BootstrapInvokeDynamic", JBootstrapInvokeDynamic.class); registerClass("Code", JCodeAttribute.class); registerClass("ConstantValue", JConstantValueAttribute.class); registerClass("EnclosingMethod", JEnclosingMethodAttribute.class); diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JBootstrapInvokeDynamic.java b/src/fjbg/ch/epfl/lamp/fjbg/JBootstrapInvokeDynamic.java deleted file mode 100644 index 91c4a465ae..0000000000 --- a/src/fjbg/ch/epfl/lamp/fjbg/JBootstrapInvokeDynamic.java +++ /dev/null @@ -1,69 +0,0 @@ -/* FJBG -- Fast Java Bytecode Generator - * Copyright 2002-2011 LAMP/EPFL - * @author Michel Schinz - */ - -package ch.epfl.lamp.fjbg; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Iterator; - -/** - * BootstrapInvokeDynamic entry, as described by JSR 292 (invoke dynamic) - * - * @author Iulian Dragos - * @version 1.0 - * - */ -public class JBootstrapInvokeDynamic extends JAttribute { - /** Constant pool of the current classfile. */ - private JConstantPool pool; - - protected final int classIdx; - - public JBootstrapInvokeDynamic(FJBGContext context, - JClass clazz, - String className) { - super(context, clazz); - this.pool = clazz.pool; - - this.classIdx = pool.addClass(className); - } - - public JBootstrapInvokeDynamic(FJBGContext context, - JClass clazz, - Object owner, - String name, - int size, - DataInputStream stream) - throws IOException { - super(context, clazz, name); - - this.classIdx = stream.readShort(); - - assert name.equals(getName()); - } - - public String getName() { return "BootstrapInvokeDynamic"; } - - // Follows javap output format for BootstrapInvokeDynamic attribute. - /*@Override*/ public String toString() { - StringBuffer buf = new StringBuffer(" BootstrapInvokeDynamic:"); - buf.append("\n #"); - buf.append(classIdx); - buf.append("; // class "); - buf.append(pool.lookupClass(classIdx)); - buf.append("\n"); - return buf.toString(); - } - - protected int getSize() { - return 2; // Short.SIZE - } - - protected void writeContentsTo(DataOutputStream stream) throws IOException { - stream.writeShort(classIdx); - } -} diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java b/src/fjbg/ch/epfl/lamp/fjbg/JClass.java index 31e30725c9..1d0bc0e19b 100644 --- a/src/fjbg/ch/epfl/lamp/fjbg/JClass.java +++ b/src/fjbg/ch/epfl/lamp/fjbg/JClass.java @@ -26,8 +26,6 @@ public class JClass extends JMember { protected final String sourceFileName; protected final JConstantPool pool; - protected JBootstrapInvokeDynamic bootstrapClassAttr = null; - public final static String[] NO_INTERFACES = new String[0]; protected final LinkedList/*<JMethod>*/ methods = new LinkedList(); @@ -307,12 +305,6 @@ public class JClass extends JMember { fStream.close(); } - public void setBootstrapClass(String bootstrapClass) { - assert bootstrapClassAttr == null; - bootstrapClassAttr = new JBootstrapInvokeDynamic(context, this, bootstrapClass); - addAttribute(bootstrapClassAttr); - } - /** * Writes the contents of the class to a data stream. * @param stream The data stream in which the class must be written. diff --git a/src/library/scala/runtime/DynamicDispatch.java-notyet b/src/library/scala/runtime/DynamicDispatch.java-notyet deleted file mode 100644 index 744ee79264..0000000000 --- a/src/library/scala/runtime/DynamicDispatch.java-notyet +++ /dev/null @@ -1,42 +0,0 @@ -package scala.runtime; - -import java.dyn.CallSite; -import java.dyn.MethodHandle; - -/** - * This class resolves calls through refinement types. The - * bootstrap method is called when an invokedynamic is found - * by the Java VM. - * - * Note: Requires Java 7 with invoke dynamic support (see JSR 292) - * - * @author Iulian Dragos - * @see JSR292 - */ -public class DynamicDispatch { - - /** - * Resolve an invoke dynamic in Scala code. invokedynamic calls appear - * when a method defined by a refinement type is called. It is resolved - * by looking up a method with the same name and types in the receiver - * object. It is guaranteed by the type checker that such a method - * exists. - * - * The current implementation is not correct, a call site being - * always bootstrapped to a method handle. A bound call site should be - * guarded by a test on the receiver type. Such code should either - * be generated by the compiler, or by this bootstrap method using - * one of the code combinators provided in java.dyn.*. - * - * ATM, they are not yet available in the JVM. - */ - public static Object bootstrapInvokeDynamic(CallSite cs, Object... args) { - println(cs); - - MethodHandle mh = MethodHandles.findVirtual(cs.callerClass(), - cs.name(), - cs.type()); - cs.setTarget(mh); - return mh(args); - } -} |