Skip to content

Flags.ModuleVal, Flags.PackageClass #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Feb 13, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 41 additions & 40 deletions src/dotty/tools/dotc/backend/jvm/BCodeBodyBuilder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import scala.annotation.switch
import dotty.tools.asm

import dotc.ast.Trees._
import core.Flags
import core.Types.Type
import core.StdNames
import core.Symbols.{Symbol, NoSymbol}
Expand Down Expand Up @@ -52,9 +53,9 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {

/* ---------------- helper utils for generating methods and code ---------------- */

def emit(opc: Int) { mnode.visitInsn(opc) }
def emit(opc: Int): Unit = { mnode.visitInsn(opc) }

def emitZeroOf(tk: BType) {
def emitZeroOf(tk: BType): Unit = {
(tk.sort: @switch) match {
case asm.Type.BOOLEAN => bc.boolconst(false)
case asm.Type.BYTE |
Expand All @@ -74,7 +75,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
* Two main cases: `tree` is an assignment,
* otherwise an `adapt()` to UNIT is performed if needed.
*/
def genStat(tree: Tree) {
def genStat(tree: Tree): Unit = {
lineNumber(tree)
tree match {
case Assign(lhs @ Select(_, _), rhs) =>
Expand Down Expand Up @@ -340,12 +341,12 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
)
}

def genLoad(tree: Tree) {
def genLoad(tree: Tree): Unit = {
genLoad(tree, tpeTK(tree))
}

/* Generate code for trees that produce values on the stack */
def genLoad(tree: Tree, expectedType: BType) {
def genLoad(tree: Tree, expectedType: BType): Unit = {
var generatedType = expectedType

lineNumber(tree)
Expand Down Expand Up @@ -392,7 +393,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
// case ApplyDynamic(qual, args) => sys.error("No invokedynamic support yet.")

case This(qual) =>
val symIsModuleClass = tree.symbol.isModuleClass
val symIsModuleClass = tree.symbol is Flags.ModuleVal
assert(tree.symbol == claszSymbol || symIsModuleClass,
s"Trying to access the this of another class: tree.symbol = ${tree.symbol}, class symbol = $claszSymbol compilation unit: $cunit")
if (symIsModuleClass && tree.symbol != claszSymbol) {
Expand All @@ -406,7 +407,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}

case Select(Ident(nme.EMPTY_PACKAGE_NAME), module) =>
assert(tree.symbol.isModule, s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.pos}")
assert(tree.symbol is Flags.ModuleVal, s"Selection of non-module from empty package: $tree sym: ${tree.symbol} at: ${tree.pos}")
genLoadModule(tree)

case Select(qualifier, selector) =>
Expand All @@ -416,9 +417,9 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
debuglog(s"Host class of $sym with qual $qualifier (${qualifier.tpe}) is $hostClass")
val qualSafeToElide = treeInfo isQualifierSafeToElide qualifier

def genLoadQualUnlessElidable() { if (!qualSafeToElide) { genLoadQualifier(tree) } }
def genLoadQualUnlessElidable(): Unit = { if (!qualSafeToElide) { genLoadQualifier(tree) } }

if (sym.isModule) {
if (sym is Flags.ModuleVal) {
genLoadQualUnlessElidable()
genLoadModule(tree)
}
Expand All @@ -435,7 +436,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val sym = tree.symbol
if (!sym.isPackage) {
val tk = symInfoTK(sym)
if (sym.isModule) { genLoadModule(tree) }
if (sym is Flags.ModuleVal) { genLoadModule(tree) }
else { locals.load(sym) }
generatedType = tk
}
Expand Down Expand Up @@ -481,20 +482,20 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
/*
* must-single-thread
*/
def fieldLoad( field: Symbol, hostClass: Symbol = null) {
def fieldLoad( field: Symbol, hostClass: Symbol = null): Unit = {
fieldOp(field, isLoad = true, hostClass)
}
/*
* must-single-thread
*/
def fieldStore(field: Symbol, hostClass: Symbol = null) {
def fieldStore(field: Symbol, hostClass: Symbol = null): Unit = {
fieldOp(field, isLoad = false, hostClass)
}

/*
* must-single-thread
*/
private def fieldOp(field: Symbol, isLoad: Boolean, hostClass: Symbol) {
private def fieldOp(field: Symbol, isLoad: Boolean, hostClass: Symbol): Unit = {
// LOAD_FIELD.hostClass , CALL_METHOD.hostClass , and #4283
val owner =
if (hostClass == null) internalName(field.owner)
Expand All @@ -516,7 +517,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
* must-single-thread
* Otherwise it's safe to call from multiple threads.
*/
def genConstant(const: Constant) {
def genConstant(const: Constant): Unit = {

import dotc.core.Constants._

Expand Down Expand Up @@ -565,15 +566,15 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}
}

private def genLabelDef(lblDf: LabelDef, expectedType: BType) {
private def genLabelDef(lblDf: LabelDef, expectedType: BType): Unit = {
// duplication of LabelDefs contained in `finally`-clauses is handled when emitting RETURN. No bookkeeping for that required here.
// no need to call index() over lblDf.params, on first access that magic happens (moreover, no LocalVariableTable entries needed for them).
markProgramPoint(programPoint(lblDf.symbol))
lineNumber(lblDf)
genLoad(lblDf.rhs, expectedType)
}

private def genReturn(r: Return) {
private def genReturn(r: Return): Unit = {
val Return(expr) = r
val returnedKind = tpeTK(expr)
genLoad(expr, returnedKind)
Expand Down Expand Up @@ -735,11 +736,11 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
generatedType = genPrimitiveOp(app, expectedType)
} else { // normal method call

def genNormalMethodCall() {
def genNormalMethodCall(): Unit = {

val invokeStyle =
if (sym.isStaticMember) icodes.opcodes.Static(onInstance = false)
else if (sym.isPrivate || sym.isClassConstructor) icodes.opcodes.Static(onInstance = true)
else if ((sym is Flags.Private) || sym.isClassConstructor) icodes.opcodes.Static(onInstance = true)
else icodes.opcodes.Dynamic;

if (invokeStyle.hasInstance) {
Expand All @@ -756,12 +757,12 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val qualSym = findHostClass(qual.tpe, sym)
if (qualSym == ArrayClass) {
targetTypeKind = tpeTK(qual)
log(s"Stored target type kind for ${sym.fullName} as $targetTypeKind")
ctx.log(s"Stored target type kind for ${sym.fullName} as $targetTypeKind")
}
else {
hostClass = qualSym
if (qual.tpe.typeSymbol != qualSym) {
log(s"Precisified host class for $sym from ${qual.tpe.typeSymbol.fullName} to ${qualSym.fullName}")
ctx.log(s"Precisified host class for $sym from ${qual.tpe.typeSymbol.fullName} to ${qualSym.fullName}")
}
}

Expand Down Expand Up @@ -870,7 +871,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
generatedType
}

def genBlock(tree: Block, expectedType: BType) {
def genBlock(tree: Block, expectedType: BType): Unit = {
val Block(stats, expr) = tree
val savedScope = varsInScope
varsInScope = Nil
Expand Down Expand Up @@ -902,7 +903,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}

/* Emit code to Load the qualifier of `tree` on top of the stack. */
def genLoadQualifier(tree: Tree) {
def genLoadQualifier(tree: Tree): Unit = {
lineNumber(tree)
tree match {
case Select(qualifier, _) => genLoad(qualifier)
Expand All @@ -911,7 +912,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}

/* Generate code that loads args into label parameters. */
def genLoadLabelArguments(args: List[Tree], lblDef: LabelDef, gotoPos: dotc.util.Positions.Position) {
def genLoadLabelArguments(args: List[Tree], lblDef: LabelDef, gotoPos: dotc.util.Positions.Position): Unit = {

val aps = {
val params: List[Symbol] = lblDef.params.map(_.symbol)
Expand Down Expand Up @@ -939,24 +940,24 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {

}

def genLoadArguments(args: List[Tree], btpes: List[BType]) {
def genLoadArguments(args: List[Tree], btpes: List[BType]): Unit = {
(args zip btpes) foreach { case (arg, btpe) => genLoad(arg, btpe) }
}

def genLoadModule(tree: Tree): BType = {
val module = (
if (!tree.symbol.isPackageClass) tree.symbol
if (!tree.symbol is Flags.PackageClass) tree.symbol
else tree.symbol.info.member(nme.PACKAGE) match {
case NoSymbol => abort(s"SI-5604: Cannot use package as value: $tree")
case s => abort(s"SI-5604: found package class where package object expected: $tree")
case NoDenotation => abort(s"SI-5604: Cannot use package as value: $tree")
case s => abort(s"SI-5604: found package class where package object expected: $tree")
}
)
lineNumber(tree)
genLoadModule(module)
symInfoTK(module)
}

def genLoadModule(module: Symbol) {
def genLoadModule(module: Symbol): Unit = {
def inStaticMethod = methSymbol != null && methSymbol.isStaticMember
if (claszSymbol == module.moduleClass && jMethodName != "readResolve" && !inStaticMethod) {
mnode.visitVarInsn(asm.Opcodes.ALOAD, 0)
Expand All @@ -971,15 +972,15 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}
}

def genConversion(from: BType, to: BType, cast: Boolean) {
def genConversion(from: BType, to: BType, cast: Boolean): Unit = {
if (cast) { bc.emitT2T(from, to) }
else {
bc drop from
bc boolconst (from == to)
}
}

def genCast(to: BType, cast: Boolean) {
def genCast(to: BType, cast: Boolean): Unit = {
if (cast) { bc checkCast to }
else { bc isInstance to }
}
Expand All @@ -988,7 +989,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def isPrimitive(fun: Symbol): Boolean = scalaPrimitives.isPrimitive(fun)

/* Generate coercion denoted by "code" */
def genCoercion(code: Int) {
def genCoercion(code: Int): Unit = {
import scalaPrimitives._
(code: @switch) match {
case B2B | S2S | C2C | I2I | L2L | F2F | D2D => ()
Expand Down Expand Up @@ -1034,8 +1035,8 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
hostSymbol.info ; methodOwner.info

def needsInterfaceCall(sym: Symbol) = (
sym.isInterface
|| sym.isJavaDefined && sym.isNonBottomSubClass(definitions.ClassfileAnnotationClass)
(sym is Flags.Interface)
|| (sym is Flags.JavaDefined) && sym.isNonBottomSubClass(definitions.ClassfileAnnotationClass)
)

// whether to reference the type of the receiver or
Expand All @@ -1052,7 +1053,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
val bmType = asmMethodType(method)
val mdescr = bmType.getDescriptor

def initModule() {
def initModule(): Unit = {
// we initialize the MODULE$ field immediately after the super ctor
if (!isModuleInitialized &&
jMethodName == INSTANCE_CONSTRUCTOR_NAME &&
Expand Down Expand Up @@ -1121,7 +1122,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
def ifOneIsNull(l: Tree, r: Tree) = if (isNull(l)) r else if (isNull(r)) l else null

/* Emit code to compare the two top-most stack values using the 'op' operator. */
private def genCJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType) {
private def genCJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType): Unit = {
if (tk.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT
bc.emitIF_ICMP(op, success)
} else if (tk.isRefOrArrayType) { // REFERENCE(_) | ARRAY(_)
Expand All @@ -1142,7 +1143,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
}

/* Emits code to compare (and consume) stack-top and zero using the 'op' operator */
private def genCZJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType) {
private def genCZJUMP(success: asm.Label, failure: asm.Label, op: TestOp, tk: BType): Unit = {
if (tk.isIntSizedType) { // BOOL, BYTE, CHAR, SHORT, or INT
bc.emitIF(op, success)
} else if (tk.isRefOrArrayType) { // REFERENCE(_) | ARRAY(_)
Expand Down Expand Up @@ -1178,9 +1179,9 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
* Generate code for conditional expressions.
* The jump targets success/failure of the test are `then-target` and `else-target` resp.
*/
private def genCond(tree: Tree, success: asm.Label, failure: asm.Label) {
private def genCond(tree: Tree, success: asm.Label, failure: asm.Label): Unit = {

def genComparisonOp(l: Tree, r: Tree, code: Int) {
def genComparisonOp(l: Tree, r: Tree, code: Int): Unit = {
val op: TestOp = testOpForPrimitive(code - scalaPrimitives.ID)
// special-case reference (in)equality test for null (null eq x, x eq null)
var nonNullSide: Tree = null
Expand Down Expand Up @@ -1213,7 +1214,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
lazy val Select(lhs, _) = fun
val rhs = if (args.isEmpty) EmptyTree else args.head; // args.isEmpty only for ZNOT

def genZandOrZor(and: Boolean) { // TODO WRONG
def genZandOrZor(and: Boolean): Unit = { // TODO WRONG
// reaching "keepGoing" indicates the rhs should be evaluated too (ie not short-circuited).
val keepGoing = new asm.Label

Expand Down Expand Up @@ -1253,7 +1254,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
* @param l left-hand-side of the '=='
* @param r right-hand-side of the '=='
*/
def genEqEqPrimitive(l: Tree, r: Tree, success: asm.Label, failure: asm.Label) {
def genEqEqPrimitive(l: Tree, r: Tree, success: asm.Label, failure: asm.Label): Unit = {

/* True if the equality comparison is between values that require the use of the rich equality
* comparator (scala.runtime.Comparator.equals). This is the case when either side of the
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/backend/jvm/BCodeGlue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ abstract class BCodeGlue {
*
* can-multi-thread
*/
private def getDescriptor(buf: StringBuffer) {
private def getDescriptor(buf: StringBuffer): Unit = {
if (isPrimitiveOrVoid) {
// descriptor is in byte 3 of 'off' for primitive types (buf == null)
buf.append(((off & 0xFF000000) >>> 24).asInstanceOf[Char])
Expand Down
Loading