diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 104 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala | 9 |
2 files changed, 63 insertions, 50 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index c158d951a7..6a3c7a000a 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -50,19 +50,22 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { def name = phaseName override def erasedTypes = true - object codeGenerator extends BytecodeGenerator override def run { + // we reinstantiate the bytecode generator at each run, to allow the GC + // to collect everything + val codeGenerator = new BytecodeGenerator if (settings.debug.value) inform("[running phase " + name + " on icode]") if (settings.Xdce.value) for ((sym, cls) <- icodes.classes if inliner.isClosureClass(sym) && !deadCode.liveClosures(sym)) icodes.classes -= sym - classes.values foreach apply + classes.values foreach codeGenerator.genClass + classes.clear } - override def apply(cls: IClass) { - codeGenerator.genClass(cls) + def apply(cls: IClass) { + error("no implementation") } } @@ -633,15 +636,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { } } - def isTopLevelModule(sym: Symbol): Boolean = - atPhase (currentRun.picklerPhase.next) { - sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass - } - - def isStaticModule(sym: Symbol): Boolean = { - sym.isModuleClass && !sym.isImplClass && !sym.isLifted - } - def genField(f: IField) { if (settings.debug.value) log("Adding field: " + f.symbol.fullName) @@ -1731,41 +1725,13 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { ////////////////////// Utilities //////////////////////// - /** - * Return the Java modifiers for the given symbol. - * Java modifiers for classes: - * - public, abstract, final, strictfp (not used) - * for interfaces: - * - the same as for classes, without 'final' - * for fields: - * - public, private (*) - * - static, final - * for methods: - * - the same as for fields, plus: - * - abstract, synchronized (not used), strictfp (not used), native (not used) - * - * (*) protected cannot be used, since inner classes 'see' protected members, - * and they would fail verification after lifted. - */ - def javaFlags(sym: Symbol): Int = { - def mkFlags(args: Int*) = args.foldLeft(0)(_ | _) - // constructors of module classes should be private - // PP: why are they only being marked private at this stage and not earlier? - val isConsideredPrivate = - sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner)) - - mkFlags( - if (isConsideredPrivate) ACC_PRIVATE else ACC_PUBLIC, - if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0, - if (sym.isInterface) ACC_INTERFACE else 0, - if (sym.isFinal && !sym.enclClass.isInterface && !sym.isClassConstructor) ACC_FINAL else 0, - if (sym.isStaticMember) ACC_STATIC else 0, - if (sym.isBridge) ACC_BRIDGE else 0, - if (sym.isClass && !sym.isInterface) ACC_SUPER else 0, - if (sym.isVarargsMethod) ACC_VARARGS else 0 - ) + override def javaName(sym: Symbol): String = { + if (sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass) + innerClasses = innerClasses + sym + super.javaName(sym) } + /** Calls to methods in 'sym' need invokeinterface? */ def needsInterfaceCall(sym: Symbol): Boolean = { log("checking for interface call: " + sym.fullName) @@ -1808,4 +1774,50 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid { def assert(cond: Boolean) { assert(cond, "Assertion failed.") } } + + /** + * Return the Java modifiers for the given symbol. + * Java modifiers for classes: + * - public, abstract, final, strictfp (not used) + * for interfaces: + * - the same as for classes, without 'final' + * for fields: + * - public, private (*) + * - static, final + * for methods: + * - the same as for fields, plus: + * - abstract, synchronized (not used), strictfp (not used), native (not used) + * + * (*) protected cannot be used, since inner classes 'see' protected members, + * and they would fail verification after lifted. + */ + def javaFlags(sym: Symbol): Int = { + def mkFlags(args: Int*) = args.foldLeft(0)(_ | _) + // constructors of module classes should be private + // PP: why are they only being marked private at this stage and not earlier? + val isConsideredPrivate = + sym.isPrivate || (sym.isPrimaryConstructor && isTopLevelModule(sym.owner)) + + mkFlags( + if (isConsideredPrivate) ACC_PRIVATE else ACC_PUBLIC, + if (sym.isDeferred || sym.hasAbstractFlag) ACC_ABSTRACT else 0, + if (sym.isInterface) ACC_INTERFACE else 0, + if (sym.isFinal && !sym.enclClass.isInterface && !sym.isClassConstructor) ACC_FINAL else 0, + if (sym.isStaticMember) ACC_STATIC else 0, + if (sym.isBridge) ACC_BRIDGE else 0, + if (sym.isClass && !sym.isInterface) ACC_SUPER else 0, + if (sym.isVarargsMethod) ACC_VARARGS else 0 + ) + } + + def isTopLevelModule(sym: Symbol): Boolean = + atPhase (currentRun.picklerPhase.next) { + sym.isModuleClass && !sym.isImplClass && !sym.isNestedClass + } + + def isStaticModule(sym: Symbol): Boolean = { + sym.isModuleClass && !sym.isImplClass && !sym.isLifted + } + + } diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala index cd0d253954..38c22b930c 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala @@ -43,8 +43,11 @@ trait GenJVMUtil { DOUBLE -> new JObjectType("java.lang.Double") ) + /** This trait may be used by tools who need access to + * utility methods like javaName and javaType. (for instance, + * the Eclipse plugin uses it). + */ trait BytecodeUtil { - self: BytecodeGenerator => val conds = immutable.Map[TestOp, Int]( EQ -> JExtendedCode.COND_EQ, @@ -84,9 +87,6 @@ trait GenJVMUtil { else getPrimitiveCompanion(sym.companionModule) match { case Some(sym) => javaName(sym) case _ => - if (sym.isClass && !sym.rawowner.isPackageClass && !sym.isModuleClass) - innerClasses = innerClasses + sym - val prefix = if (sym.isClass || (sym.isModule && !sym.isMethod)) sym.fullName('/') else sym.simpleName.toString.trim() @@ -132,6 +132,7 @@ trait GenJVMUtil { ts foreach ( t => { res(i) = javaType(t); i += 1 } ); res } + protected def genConstant(jcode: JExtendedCode, const: Constant) { const.tag match { case UnitTag => () |