summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-03-05 16:05:01 +0100
committerMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-03-05 16:05:01 +0100
commitc9bee28c8f5aaa77005043e1491e4e06ec7bce5e (patch)
tree4d5217a5a85a4d32ed86b81d4dc1e099a0c7ee36
parent891b763071d5ee460a9c5f931eb4c44482d14eb4 (diff)
downloadscala-c9bee28c8f5aaa77005043e1491e4e06ec7bce5e.tar.gz
scala-c9bee28c8f5aaa77005043e1491e4e06ec7bce5e.tar.bz2
scala-c9bee28c8f5aaa77005043e1491e4e06ec7bce5e.zip
making indentation IDE-aware
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala1110
1 files changed, 555 insertions, 555 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index aac777b71c..0c5debacc7 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -1135,625 +1135,625 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with
case x :: y :: ys => nextBlock = y; genBlock(x); genBlocks(y :: ys)
}
- /** Generate exception handlers for the current method. */
- def genExceptionHandlers() {
+ /** Generate exception handlers for the current method. */
+ def genExceptionHandlers() {
- /** Return a list of pairs of intervals where the handler is active.
- * The intervals in the list have to be inclusive in the beginning and
- * exclusive in the end: [start, end).
- */
- def ranges(e: ExceptionHandler): List[(Int, Int)] = {
- var covered = e.covered
- var ranges: List[(Int, Int)] = Nil
- var start = -1
- var end = -1
-
- linearization foreach { b =>
- if (! (covered contains b) ) {
- if (start >= 0) { // we're inside a handler range
- end = labels(b).getAnchor()
- ranges ::= ((start, end))
- start = -1
+ /** Return a list of pairs of intervals where the handler is active.
+ * The intervals in the list have to be inclusive in the beginning and
+ * exclusive in the end: [start, end).
+ */
+ def ranges(e: ExceptionHandler): List[(Int, Int)] = {
+ var covered = e.covered
+ var ranges: List[(Int, Int)] = Nil
+ var start = -1
+ var end = -1
+
+ linearization foreach { b =>
+ if (! (covered contains b) ) {
+ if (start >= 0) { // we're inside a handler range
+ end = labels(b).getAnchor()
+ ranges ::= ((start, end))
+ start = -1
+ }
+ } else {
+ if (start < 0) // we're not inside a handler range
+ start = labels(b).getAnchor()
+
+ end = endPC(b)
+ covered -= b
}
- } else {
- if (start < 0) // we're not inside a handler range
- start = labels(b).getAnchor()
+ }
- end = endPC(b)
- covered -= b
+ /* Add the last interval. Note that since the intervals are
+ * open-ended to the right, we have to give a number past the actual
+ * code!
+ */
+ if (start >= 0) {
+ ranges ::= ((start, jcode.getPC()))
}
- }
- /* Add the last interval. Note that since the intervals are
- * open-ended to the right, we have to give a number past the actual
- * code!
- */
- if (start >= 0) {
- ranges ::= ((start, jcode.getPC()))
+ if (!covered.isEmpty)
+ debuglog("Some covered blocks were not found in method: " + method +
+ " covered: " + covered + " not in " + linearization)
+ ranges
}
- if (!covered.isEmpty)
- debuglog("Some covered blocks were not found in method: " + method +
- " covered: " + covered + " not in " + linearization)
- ranges
- }
-
- for (e <- this.method.exh ; p <- ranges(e).sortBy(_._1)) {
- if (p._1 < p._2) {
- debuglog("Adding exception handler " + e + "at block: " + e.startBlock + " for " + method +
- " from: " + p._1 + " to: " + p._2 + " catching: " + e.cls);
- val cls = if (e.cls == NoSymbol || e.cls == ThrowableClass) null
- else javaName(e.cls)
- jcode.addExceptionHandler(p._1, p._2,
- labels(e.startBlock).getAnchor(),
- cls)
- } else
- log("Empty exception range: " + p)
+ for (e <- this.method.exh ; p <- ranges(e).sortBy(_._1)) {
+ if (p._1 < p._2) {
+ debuglog("Adding exception handler " + e + "at block: " + e.startBlock + " for " + method +
+ " from: " + p._1 + " to: " + p._2 + " catching: " + e.cls);
+ val cls = if (e.cls == NoSymbol || e.cls == ThrowableClass) null
+ else javaName(e.cls)
+ jcode.addExceptionHandler(p._1, p._2,
+ labels(e.startBlock).getAnchor(),
+ cls)
+ } else
+ log("Empty exception range: " + p)
+ }
}
- }
- def isAccessibleFrom(target: Symbol, site: Symbol): Boolean = {
- target.isPublic || target.isProtected && {
- (site.enclClass isSubClass target.enclClass) ||
- (site.enclosingPackage == target.privateWithin)
+ 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 && methodOwner != ObjectClass
- || 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) {
- debuglog("%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 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 && methodOwner != ObjectClass
+ || 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) {
+ debuglog("%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())
+ 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()
+ 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()
-
- debuglog("Generating code for block: " + b + " at pc: " + labels(b).getAnchor())
- var lastMappedPC = 0
- var lastLineNr = 0
- var crtPC = 0
- /** local variables whose scope appears in this block. */
- val varsInBlock: mutable.Set[Local] = new mutable.HashSet
+ def genBlock(b: BasicBlock) {
+ labels(b).anchorToNext()
- for (instr <- b) {
+ debuglog("Generating code for block: " + b + " at pc: " + labels(b).getAnchor())
+ var lastMappedPC = 0
+ var lastLineNr = 0
+ var crtPC = 0
- instr match {
- case THIS(clasz) =>
- jcode.emitALOAD_0()
-
- case CONSTANT(const) =>
- genConstant(jcode, const)
-
- case LOAD_ARRAY_ITEM(kind) =>
- jcode.emitALOAD(javaType(kind))
+ /** local variables whose scope appears in this block. */
+ val varsInBlock: mutable.Set[Local] = new mutable.HashSet
- case LOAD_LOCAL(local) =>
- jcode.emitLOAD(indexOf(local), javaType(local.kind))
+ for (instr <- b) {
- case lf @ LOAD_FIELD(field, isStatic) =>
- var owner = javaName(lf.hostClass)
- debuglog("LOAD_FIELD with owner: " + owner +
- " flags: " + Flags.flagsToString(field.owner.flags))
- if (isStatic)
- jcode.emitGETSTATIC(owner,
- javaName(field),
- javaType(field))
- else
- jcode.emitGETFIELD(owner,
- javaName(field),
- javaType(field))
-
- case LOAD_MODULE(module) =>
-// assert(module.isModule, "Expected module: " + module)
- debuglog("generating LOAD_MODULE for: " + module + " flags: " +
- Flags.flagsToString(module.flags));
- if (clasz.symbol == module.moduleClass && jmethod.getName() != nme.readResolve.toString)
+ instr match {
+ case THIS(clasz) =>
jcode.emitALOAD_0()
- else
- jcode.emitGETSTATIC(javaName(module) /* + "$" */ ,
- nme.MODULE_INSTANCE_FIELD.toString,
- javaType(module))
-
- case STORE_ARRAY_ITEM(kind) =>
- jcode emitASTORE javaType(kind)
-
- case STORE_LOCAL(local) =>
- jcode.emitSTORE(indexOf(local), javaType(local.kind))
-
- case STORE_THIS(_) =>
- // this only works for impl classes because the self parameter comes first
- // in the method signature. If that changes, this code has to be revisited.
- jcode.emitASTORE_0()
-
- case STORE_FIELD(field, isStatic) =>
- val owner = javaName(field.owner)
- if (isStatic)
- jcode.emitPUTSTATIC(owner,
- javaName(field),
- javaType(field))
- else
- jcode.emitPUTFIELD(owner,
- javaName(field),
- javaType(field))
-
- case CALL_PRIMITIVE(primitive) =>
- genPrimitive(primitive, instr.pos)
-
- /** Special handling to access native Array.clone() */
- case call @ CALL_METHOD(definitions.Array_clone, Dynamic) =>
- val target: String = javaType(call.targetTypeKind).getSignature()
- jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType)
-
- case call @ CALL_METHOD(method, style) =>
- genCallMethod(call)
-
- case BOX(kind) =>
- val boxedType = definitions.boxedClass(kind.toType.typeSymbol)
- val mtype = new JMethodType(javaType(boxedType), Array(javaType(kind)))
- jcode.emitINVOKESTATIC(BoxesRunTime, "boxTo" + boxedType.decodedName, mtype)
-
- case UNBOX(kind) =>
- val mtype = new JMethodType(javaType(kind), Array(JAVA_LANG_OBJECT))
- jcode.emitINVOKESTATIC(BoxesRunTime, "unboxTo" + kind.toType.typeSymbol.decodedName, mtype)
-
- case NEW(REFERENCE(cls)) =>
- val className = javaName(cls)
- jcode emitNEW className
-
- case CREATE_ARRAY(elem, 1) => elem match {
- case REFERENCE(_) | ARRAY(_) =>
- jcode emitANEWARRAY javaType(elem).asInstanceOf[JReferenceType]
- case _ =>
- jcode emitNEWARRAY javaType(elem)
- }
- case CREATE_ARRAY(elem, dims) =>
- jcode.emitMULTIANEWARRAY(javaType(ArrayN(elem, dims)).asInstanceOf[JReferenceType], dims)
-
- case IS_INSTANCE(tpe) =>
- tpe match {
- case REFERENCE(cls) =>
- jcode emitINSTANCEOF new JObjectType(javaName(cls))
- case ARRAY(elem) =>
- jcode emitINSTANCEOF new JArrayType(javaType(elem))
+ case CONSTANT(const) =>
+ genConstant(jcode, const)
+
+ case LOAD_ARRAY_ITEM(kind) =>
+ jcode.emitALOAD(javaType(kind))
+
+ case LOAD_LOCAL(local) =>
+ jcode.emitLOAD(indexOf(local), javaType(local.kind))
+
+ case lf @ LOAD_FIELD(field, isStatic) =>
+ var owner = javaName(lf.hostClass)
+ debuglog("LOAD_FIELD with owner: " + owner +
+ " flags: " + Flags.flagsToString(field.owner.flags))
+ if (isStatic)
+ jcode.emitGETSTATIC(owner,
+ javaName(field),
+ javaType(field))
+ else
+ jcode.emitGETFIELD(owner,
+ javaName(field),
+ javaType(field))
+
+ case LOAD_MODULE(module) =>
+ // assert(module.isModule, "Expected module: " + module)
+ debuglog("generating LOAD_MODULE for: " + module + " flags: " +
+ Flags.flagsToString(module.flags));
+ if (clasz.symbol == module.moduleClass && jmethod.getName() != nme.readResolve.toString)
+ jcode.emitALOAD_0()
+ else
+ jcode.emitGETSTATIC(javaName(module) /* + "$" */ ,
+ nme.MODULE_INSTANCE_FIELD.toString,
+ javaType(module))
+
+ case STORE_ARRAY_ITEM(kind) =>
+ jcode emitASTORE javaType(kind)
+
+ case STORE_LOCAL(local) =>
+ jcode.emitSTORE(indexOf(local), javaType(local.kind))
+
+ case STORE_THIS(_) =>
+ // this only works for impl classes because the self parameter comes first
+ // in the method signature. If that changes, this code has to be revisited.
+ jcode.emitASTORE_0()
+
+ case STORE_FIELD(field, isStatic) =>
+ val owner = javaName(field.owner)
+ if (isStatic)
+ jcode.emitPUTSTATIC(owner,
+ javaName(field),
+ javaType(field))
+ else
+ jcode.emitPUTFIELD(owner,
+ javaName(field),
+ javaType(field))
+
+ case CALL_PRIMITIVE(primitive) =>
+ genPrimitive(primitive, instr.pos)
+
+ /** Special handling to access native Array.clone() */
+ case call @ CALL_METHOD(definitions.Array_clone, Dynamic) =>
+ val target: String = javaType(call.targetTypeKind).getSignature()
+ jcode.emitINVOKEVIRTUAL(target, "clone", arrayCloneType)
+
+ case call @ CALL_METHOD(method, style) =>
+ genCallMethod(call)
+
+ case BOX(kind) =>
+ val boxedType = definitions.boxedClass(kind.toType.typeSymbol)
+ val mtype = new JMethodType(javaType(boxedType), Array(javaType(kind)))
+ jcode.emitINVOKESTATIC(BoxesRunTime, "boxTo" + boxedType.decodedName, mtype)
+
+ case UNBOX(kind) =>
+ val mtype = new JMethodType(javaType(kind), Array(JAVA_LANG_OBJECT))
+ jcode.emitINVOKESTATIC(BoxesRunTime, "unboxTo" + kind.toType.typeSymbol.decodedName, mtype)
+
+ case NEW(REFERENCE(cls)) =>
+ val className = javaName(cls)
+ jcode emitNEW className
+
+ case CREATE_ARRAY(elem, 1) => elem match {
+ case REFERENCE(_) | ARRAY(_) =>
+ jcode emitANEWARRAY javaType(elem).asInstanceOf[JReferenceType]
case _ =>
- abort("Unknown reference type in IS_INSTANCE: " + tpe)
+ jcode emitNEWARRAY javaType(elem)
}
- case CHECK_CAST(tpe) =>
- tpe match {
- case REFERENCE(cls) =>
- // No need to checkcast for Objects
- if (cls != ObjectClass)
- jcode emitCHECKCAST new JObjectType(javaName(cls))
- case ARRAY(elem) =>
- jcode emitCHECKCAST new JArrayType(javaType(elem))
- case _ =>
- abort("Unknown reference type in IS_INSTANCE: " + tpe)
- }
+ case CREATE_ARRAY(elem, dims) =>
+ jcode.emitMULTIANEWARRAY(javaType(ArrayN(elem, dims)).asInstanceOf[JReferenceType], dims)
- case SWITCH(tags, branches) =>
- val tagArray = new Array[Array[Int]](tags.length)
- var caze = tags
- var i = 0
+ case IS_INSTANCE(tpe) =>
+ tpe match {
+ case REFERENCE(cls) =>
+ jcode emitINSTANCEOF new JObjectType(javaName(cls))
+ case ARRAY(elem) =>
+ jcode emitINSTANCEOF new JArrayType(javaType(elem))
+ case _ =>
+ abort("Unknown reference type in IS_INSTANCE: " + tpe)
+ }
- while (i < tagArray.length) {
- tagArray(i) = new Array[Int](caze.head.length)
- caze.head.copyToArray(tagArray(i), 0)
- i += 1
- caze = caze.tail
- }
- val branchArray = jcode.newLabels(tagArray.length)
- i = 0
- while (i < branchArray.length) {
- branchArray(i) = labels(branches(i))
- i += 1
- }
- debuglog("Emitting SWITCH:\ntags: " + tags + "\nbranches: " + branches)
- jcode.emitSWITCH(tagArray,
- branchArray,
- labels(branches.last),
- MIN_SWITCH_DENSITY)
- ()
-
- case JUMP(whereto) =>
- if (nextBlock != whereto)
- jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps
-
- case CJUMP(success, failure, cond, kind) =>
- kind match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- if (nextBlock == success) {
- jcode.emitIF_ICMP(conds(negate(cond)), labels(failure))
- // .. and fall through to success label
- } else {
- jcode.emitIF_ICMP(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
+ case CHECK_CAST(tpe) =>
+ tpe match {
+ case REFERENCE(cls) =>
+ // No need to checkcast for Objects
+ if (cls != ObjectClass)
+ jcode emitCHECKCAST new JObjectType(javaName(cls))
+ case ARRAY(elem) =>
+ jcode emitCHECKCAST new JArrayType(javaType(elem))
+ case _ =>
+ abort("Unknown reference type in IS_INSTANCE: " + tpe)
+ }
- case REFERENCE(_) | ARRAY(_) =>
- if (nextBlock == success) {
- jcode.emitIF_ACMP(conds(negate(cond)), labels(failure))
- // .. and fall through to success label
- } else {
- jcode.emitIF_ACMP(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
+ case SWITCH(tags, branches) =>
+ val tagArray = new Array[Array[Int]](tags.length)
+ var caze = tags
+ var i = 0
- case _ =>
- (kind: @unchecked) match {
- case LONG => jcode.emitLCMP()
- case FLOAT =>
- if (cond == LT || cond == LE) jcode.emitFCMPG()
- else jcode.emitFCMPL()
- case DOUBLE =>
- if (cond == LT || cond == LE) jcode.emitDCMPG()
- else jcode.emitDCMPL()
- }
- if (nextBlock == success) {
- jcode.emitIF(conds(negate(cond)), labels(failure))
- // .. and fall through to success label
- } else {
- jcode.emitIF(conds(cond), labels(success));
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
- }
+ while (i < tagArray.length) {
+ tagArray(i) = new Array[Int](caze.head.length)
+ caze.head.copyToArray(tagArray(i), 0)
+ i += 1
+ caze = caze.tail
+ }
+ val branchArray = jcode.newLabels(tagArray.length)
+ i = 0
+ while (i < branchArray.length) {
+ branchArray(i) = labels(branches(i))
+ i += 1
+ }
+ debuglog("Emitting SWITCH:\ntags: " + tags + "\nbranches: " + branches)
+ jcode.emitSWITCH(tagArray,
+ branchArray,
+ labels(branches.last),
+ MIN_SWITCH_DENSITY)
+ ()
+
+ case JUMP(whereto) =>
+ if (nextBlock != whereto)
+ jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps
+
+ case CJUMP(success, failure, cond, kind) =>
+ kind match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ if (nextBlock == success) {
+ jcode.emitIF_ICMP(conds(negate(cond)), labels(failure))
+ // .. and fall through to success label
+ } else {
+ jcode.emitIF_ICMP(conds(cond), labels(success))
+ if (nextBlock != failure)
+ jcode.emitGOTO_maybe_W(labels(failure), false)
+ }
+
+ case REFERENCE(_) | ARRAY(_) =>
+ if (nextBlock == success) {
+ jcode.emitIF_ACMP(conds(negate(cond)), labels(failure))
+ // .. and fall through to success label
+ } else {
+ jcode.emitIF_ACMP(conds(cond), labels(success))
+ if (nextBlock != failure)
+ jcode.emitGOTO_maybe_W(labels(failure), false)
+ }
- case CZJUMP(success, failure, cond, kind) =>
- kind match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- if (nextBlock == success) {
- jcode.emitIF(conds(negate(cond)), labels(failure))
- } else {
- jcode.emitIF(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
+ case _ =>
+ (kind: @unchecked) match {
+ case LONG => jcode.emitLCMP()
+ case FLOAT =>
+ if (cond == LT || cond == LE) jcode.emitFCMPG()
+ else jcode.emitFCMPL()
+ case DOUBLE =>
+ if (cond == LT || cond == LE) jcode.emitDCMPG()
+ else jcode.emitDCMPL()
+ }
+ if (nextBlock == success) {
+ jcode.emitIF(conds(negate(cond)), labels(failure))
+ // .. and fall through to success label
+ } else {
+ jcode.emitIF(conds(cond), labels(success));
+ if (nextBlock != failure)
+ jcode.emitGOTO_maybe_W(labels(failure), false)
+ }
+ }
- case REFERENCE(_) | ARRAY(_) =>
- val Success = success
- val Failure = failure
- (cond, nextBlock) match {
- case (EQ, Success) =>
- jcode emitIFNONNULL labels(failure)
- case (NE, Failure) =>
- jcode emitIFNONNULL labels(success)
- case (EQ, Failure) =>
- jcode emitIFNULL labels(success)
- case (NE, Success) =>
- jcode emitIFNULL labels(failure)
- case (EQ, _) =>
- jcode emitIFNULL labels(success)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- case (NE, _) =>
- jcode emitIFNONNULL labels(success)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
+ case CZJUMP(success, failure, cond, kind) =>
+ kind match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ if (nextBlock == success) {
+ jcode.emitIF(conds(negate(cond)), labels(failure))
+ } else {
+ jcode.emitIF(conds(cond), labels(success))
+ if (nextBlock != failure)
+ jcode.emitGOTO_maybe_W(labels(failure), false)
+ }
+
+ case REFERENCE(_) | ARRAY(_) =>
+ val Success = success
+ val Failure = failure
+ (cond, nextBlock) match {
+ case (EQ, Success) =>
+ jcode emitIFNONNULL labels(failure)
+ case (NE, Failure) =>
+ jcode emitIFNONNULL labels(success)
+ case (EQ, Failure) =>
+ jcode emitIFNULL labels(success)
+ case (NE, Success) =>
+ jcode emitIFNULL labels(failure)
+ case (EQ, _) =>
+ jcode emitIFNULL labels(success)
+ jcode.emitGOTO_maybe_W(labels(failure), false)
+ case (NE, _) =>
+ jcode emitIFNONNULL labels(success)
+ jcode.emitGOTO_maybe_W(labels(failure), false)
+ }
- case _ =>
- (kind: @unchecked) match {
- case LONG =>
- jcode.emitLCONST_0(); jcode.emitLCMP()
- case FLOAT =>
- jcode.emitFCONST_0()
- if (cond == LT || cond == LE) jcode.emitFCMPG()
- else jcode.emitFCMPL()
- case DOUBLE =>
- jcode.emitDCONST_0()
- if (cond == LT || cond == LE) jcode.emitDCMPG()
- else jcode.emitDCMPL()
- }
- if (nextBlock == success) {
- jcode.emitIF(conds(negate(cond)), labels(failure))
- } else {
- jcode.emitIF(conds(cond), labels(success))
- if (nextBlock != failure)
- jcode.emitGOTO_maybe_W(labels(failure), false)
- }
- }
+ case _ =>
+ (kind: @unchecked) match {
+ case LONG =>
+ jcode.emitLCONST_0(); jcode.emitLCMP()
+ case FLOAT =>
+ jcode.emitFCONST_0()
+ if (cond == LT || cond == LE) jcode.emitFCMPG()
+ else jcode.emitFCMPL()
+ case DOUBLE =>
+ jcode.emitDCONST_0()
+ if (cond == LT || cond == LE) jcode.emitDCMPG()
+ else jcode.emitDCMPL()
+ }
+ if (nextBlock == success) {
+ jcode.emitIF(conds(negate(cond)), labels(failure))
+ } else {
+ jcode.emitIF(conds(cond), labels(success))
+ if (nextBlock != failure)
+ jcode.emitGOTO_maybe_W(labels(failure), false)
+ }
+ }
- case RETURN(kind) =>
- jcode emitRETURN javaType(kind)
+ case RETURN(kind) =>
+ jcode emitRETURN javaType(kind)
- case THROW(_) =>
- jcode.emitATHROW()
+ case THROW(_) =>
+ jcode.emitATHROW()
- case DROP(kind) =>
- kind match {
- case LONG | DOUBLE => jcode.emitPOP2()
- case _ => jcode.emitPOP()
- }
+ case DROP(kind) =>
+ kind match {
+ case LONG | DOUBLE => jcode.emitPOP2()
+ case _ => jcode.emitPOP()
+ }
- case DUP(kind) =>
- kind match {
- case LONG | DOUBLE => jcode.emitDUP2()
- case _ => jcode.emitDUP()
- }
+ case DUP(kind) =>
+ kind match {
+ case LONG | DOUBLE => jcode.emitDUP2()
+ case _ => jcode.emitDUP()
+ }
- case MONITOR_ENTER() =>
- jcode.emitMONITORENTER()
+ case MONITOR_ENTER() =>
+ jcode.emitMONITORENTER()
- case MONITOR_EXIT() =>
- jcode.emitMONITOREXIT()
+ case MONITOR_EXIT() =>
+ jcode.emitMONITOREXIT()
- case SCOPE_ENTER(lv) =>
- varsInBlock += lv
- lv.start = jcode.getPC()
+ case SCOPE_ENTER(lv) =>
+ varsInBlock += lv
+ lv.start = jcode.getPC()
- case SCOPE_EXIT(lv) =>
- if (varsInBlock(lv)) {
- lv.ranges = (lv.start, jcode.getPC()) :: lv.ranges
- varsInBlock -= lv
- }
- else if (b.varsInScope(lv)) {
- lv.ranges = (labels(b).getAnchor(), jcode.getPC()) :: lv.ranges
- b.varsInScope -= lv
- }
- else dumpMethodAndAbort(method, "Illegal local var nesting")
+ case SCOPE_EXIT(lv) =>
+ if (varsInBlock(lv)) {
+ lv.ranges = (lv.start, jcode.getPC()) :: lv.ranges
+ varsInBlock -= lv
+ }
+ else if (b.varsInScope(lv)) {
+ lv.ranges = (labels(b).getAnchor(), jcode.getPC()) :: lv.ranges
+ b.varsInScope -= lv
+ }
+ else dumpMethodAndAbort(method, "Illegal local var nesting")
- case LOAD_EXCEPTION(_) =>
- ()
- }
+ case LOAD_EXCEPTION(_) =>
+ ()
+ }
- crtPC = jcode.getPC()
+ crtPC = jcode.getPC()
-// assert(instr.pos.source.isEmpty || instr.pos.source.get == (clasz.cunit.source), "sources don't match")
-// val crtLine = instr.pos.line.get(lastLineNr);
+ // assert(instr.pos.source.isEmpty || instr.pos.source.get == (clasz.cunit.source), "sources don't match")
+ // val crtLine = instr.pos.line.get(lastLineNr);
- val crtLine = try {
- if (instr.pos == NoPosition) lastLineNr else (instr.pos).line // check NoPosition to avoid costly exception
- } catch {
- case _: UnsupportedOperationException =>
- log("Warning: wrong position in: " + method)
- lastLineNr
- }
+ val crtLine = try {
+ if (instr.pos == NoPosition) lastLineNr else (instr.pos).line // check NoPosition to avoid costly exception
+ } catch {
+ case _: UnsupportedOperationException =>
+ log("Warning: wrong position in: " + method)
+ lastLineNr
+ }
- if (b.lastInstruction == instr)
- endPC(b) = jcode.getPC()
+ if (b.lastInstruction == instr)
+ endPC(b) = jcode.getPC()
- //System.err.println("CRTLINE: " + instr.pos + " " +
- // /* (if (instr.pos < clasz.cunit.source.content.length) clasz.cunit.source.content(instr.pos) else '*') + */ " " + crtLine);
+ //System.err.println("CRTLINE: " + instr.pos + " " +
+ // /* (if (instr.pos < clasz.cunit.source.content.length) clasz.cunit.source.content(instr.pos) else '*') + */ " " + crtLine);
- if (crtPC > lastMappedPC) {
- jcode.completeLineNumber(lastMappedPC, crtPC, crtLine)
- lastMappedPC = crtPC
- lastLineNr = crtLine
+ if (crtPC > lastMappedPC) {
+ jcode.completeLineNumber(lastMappedPC, crtPC, crtLine)
+ lastMappedPC = crtPC
+ lastLineNr = crtLine
+ }
}
- }
- // local vars that survived this basic block
- for (lv <- varsInBlock) {
- lv.ranges = (lv.start, jcode.getPC()) :: lv.ranges
- }
- for (lv <- b.varsInScope) {
- lv.ranges = (labels(b).getAnchor(), jcode.getPC()) :: lv.ranges
+ // local vars that survived this basic block
+ for (lv <- varsInBlock) {
+ lv.ranges = (lv.start, jcode.getPC()) :: lv.ranges
+ }
+ for (lv <- b.varsInScope) {
+ lv.ranges = (labels(b).getAnchor(), jcode.getPC()) :: lv.ranges
+ }
}
- }
-
-
- /**
- * @param primitive ...
- * @param pos ...
- */
- def genPrimitive(primitive: Primitive, pos: Position) {
- primitive match {
- case Negation(kind) =>
- kind match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- jcode.emitINEG()
- case LONG => jcode.emitLNEG()
- case FLOAT => jcode.emitFNEG()
- case DOUBLE => jcode.emitDNEG()
- case _ => abort("Impossible to negate a " + kind)
- }
- case Arithmetic(op, kind) =>
- op match {
- case ADD => jcode.emitADD(javaType(kind))
- case SUB =>
- (kind: @unchecked) match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- jcode.emitISUB()
- case LONG => jcode.emitLSUB()
- case FLOAT => jcode.emitFSUB()
- case DOUBLE => jcode.emitDSUB()
- }
- case MUL =>
- (kind: @unchecked) match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- jcode.emitIMUL()
- case LONG => jcode.emitLMUL()
- case FLOAT => jcode.emitFMUL()
- case DOUBLE => jcode.emitDMUL()
- }
-
- case DIV =>
- (kind: @unchecked) match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- jcode.emitIDIV()
- case LONG => jcode.emitLDIV()
- case FLOAT => jcode.emitFDIV()
- case DOUBLE => jcode.emitDDIV()
- }
+ /**
+ * @param primitive ...
+ * @param pos ...
+ */
+ def genPrimitive(primitive: Primitive, pos: Position) {
+ primitive match {
+ case Negation(kind) =>
+ kind match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ jcode.emitINEG()
+ case LONG => jcode.emitLNEG()
+ case FLOAT => jcode.emitFNEG()
+ case DOUBLE => jcode.emitDNEG()
+ case _ => abort("Impossible to negate a " + kind)
+ }
- case REM =>
- (kind: @unchecked) match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- jcode.emitIREM()
- case LONG => jcode.emitLREM()
- case FLOAT => jcode.emitFREM()
- case DOUBLE => jcode.emitDREM()
- }
+ case Arithmetic(op, kind) =>
+ op match {
+ case ADD => jcode.emitADD(javaType(kind))
+ case SUB =>
+ (kind: @unchecked) match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ jcode.emitISUB()
+ case LONG => jcode.emitLSUB()
+ case FLOAT => jcode.emitFSUB()
+ case DOUBLE => jcode.emitDSUB()
+ }
- case NOT =>
- kind match {
- case BOOL | BYTE | CHAR | SHORT | INT =>
- jcode.emitPUSH(-1)
- jcode.emitIXOR()
- case LONG =>
- jcode.emitPUSH(-1l)
- jcode.emitLXOR()
- case _ =>
- abort("Impossible to negate an " + kind)
- }
+ case MUL =>
+ (kind: @unchecked) match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ jcode.emitIMUL()
+ case LONG => jcode.emitLMUL()
+ case FLOAT => jcode.emitFMUL()
+ case DOUBLE => jcode.emitDMUL()
+ }
- case _ =>
- abort("Unknown arithmetic primitive " + primitive)
- }
+ case DIV =>
+ (kind: @unchecked) match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ jcode.emitIDIV()
+ case LONG => jcode.emitLDIV()
+ case FLOAT => jcode.emitFDIV()
+ case DOUBLE => jcode.emitDDIV()
+ }
- case Logical(op, kind) => (op, kind) match {
- case (AND, LONG) =>
- jcode.emitLAND()
- case (AND, INT) =>
- jcode.emitIAND()
- case (AND, _) =>
- jcode.emitIAND()
- if (kind != BOOL)
- jcode.emitT2T(javaType(INT), javaType(kind));
-
- case (OR, LONG) =>
- jcode.emitLOR()
- case (OR, INT) =>
- jcode.emitIOR()
- case (OR, _) =>
- jcode.emitIOR()
- if (kind != BOOL)
- jcode.emitT2T(javaType(INT), javaType(kind));
-
- case (XOR, LONG) =>
- jcode.emitLXOR()
- case (XOR, INT) =>
- jcode.emitIXOR()
- case (XOR, _) =>
- jcode.emitIXOR()
- if (kind != BOOL)
- jcode.emitT2T(javaType(INT), javaType(kind));
- }
+ case REM =>
+ (kind: @unchecked) match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ jcode.emitIREM()
+ case LONG => jcode.emitLREM()
+ case FLOAT => jcode.emitFREM()
+ case DOUBLE => jcode.emitDREM()
+ }
- case Shift(op, kind) => (op, kind) match {
- case (LSL, LONG) =>
- jcode.emitLSHL()
- case (LSL, INT) =>
- jcode.emitISHL()
- case (LSL, _) =>
- jcode.emitISHL()
- jcode.emitT2T(javaType(INT), javaType(kind))
-
- case (ASR, LONG) =>
- jcode.emitLSHR()
- case (ASR, INT) =>
- jcode.emitISHR()
- case (ASR, _) =>
- jcode.emitISHR()
- jcode.emitT2T(javaType(INT), javaType(kind))
-
- case (LSR, LONG) =>
- jcode.emitLUSHR()
- case (LSR, INT) =>
- jcode.emitIUSHR()
- case (LSR, _) =>
- jcode.emitIUSHR()
- jcode.emitT2T(javaType(INT), javaType(kind))
- }
+ case NOT =>
+ kind match {
+ case BOOL | BYTE | CHAR | SHORT | INT =>
+ jcode.emitPUSH(-1)
+ jcode.emitIXOR()
+ case LONG =>
+ jcode.emitPUSH(-1l)
+ jcode.emitLXOR()
+ case _ =>
+ abort("Impossible to negate an " + kind)
+ }
- case Comparison(op, kind) => ((op, kind): @unchecked) match {
- case (CMP, LONG) => jcode.emitLCMP()
- case (CMPL, FLOAT) => jcode.emitFCMPL()
- case (CMPG, FLOAT) => jcode.emitFCMPG()
- case (CMPL, DOUBLE) => jcode.emitDCMPL()
- case (CMPG, DOUBLE) => jcode.emitDCMPL()
- }
+ case _ =>
+ abort("Unknown arithmetic primitive " + primitive)
+ }
- case Conversion(src, dst) =>
- debuglog("Converting from: " + src + " to: " + dst)
- if (dst == BOOL) {
- println("Illegal conversion at: " + clasz +
- " at: " + pos.source + ":" + pos.line)
- } else
- jcode.emitT2T(javaType(src), javaType(dst))
+ case Logical(op, kind) => (op, kind) match {
+ case (AND, LONG) =>
+ jcode.emitLAND()
+ case (AND, INT) =>
+ jcode.emitIAND()
+ case (AND, _) =>
+ jcode.emitIAND()
+ if (kind != BOOL)
+ jcode.emitT2T(javaType(INT), javaType(kind));
+
+ case (OR, LONG) =>
+ jcode.emitLOR()
+ case (OR, INT) =>
+ jcode.emitIOR()
+ case (OR, _) =>
+ jcode.emitIOR()
+ if (kind != BOOL)
+ jcode.emitT2T(javaType(INT), javaType(kind));
+
+ case (XOR, LONG) =>
+ jcode.emitLXOR()
+ case (XOR, INT) =>
+ jcode.emitIXOR()
+ case (XOR, _) =>
+ jcode.emitIXOR()
+ if (kind != BOOL)
+ jcode.emitT2T(javaType(INT), javaType(kind));
+ }
- case ArrayLength(_) =>
- jcode.emitARRAYLENGTH()
+ case Shift(op, kind) => (op, kind) match {
+ case (LSL, LONG) =>
+ jcode.emitLSHL()
+ case (LSL, INT) =>
+ jcode.emitISHL()
+ case (LSL, _) =>
+ jcode.emitISHL()
+ jcode.emitT2T(javaType(INT), javaType(kind))
+
+ case (ASR, LONG) =>
+ jcode.emitLSHR()
+ case (ASR, INT) =>
+ jcode.emitISHR()
+ case (ASR, _) =>
+ jcode.emitISHR()
+ jcode.emitT2T(javaType(INT), javaType(kind))
+
+ case (LSR, LONG) =>
+ jcode.emitLUSHR()
+ case (LSR, INT) =>
+ jcode.emitIUSHR()
+ case (LSR, _) =>
+ jcode.emitIUSHR()
+ jcode.emitT2T(javaType(INT), javaType(kind))
+ }
- case StartConcat =>
- jcode emitNEW StringBuilderClassName
- jcode.emitDUP()
- jcode.emitINVOKESPECIAL(StringBuilderClassName,
- JMethod.INSTANCE_CONSTRUCTOR_NAME,
- JMethodType.ARGLESS_VOID_FUNCTION)
-
- case StringConcat(el) =>
- val jtype = el match {
- case REFERENCE(_) | ARRAY(_) => JAVA_LANG_OBJECT
- case _ => javaType(el)
+ case Comparison(op, kind) => ((op, kind): @unchecked) match {
+ case (CMP, LONG) => jcode.emitLCMP()
+ case (CMPL, FLOAT) => jcode.emitFCMPL()
+ case (CMPG, FLOAT) => jcode.emitFCMPG()
+ case (CMPL, DOUBLE) => jcode.emitDCMPL()
+ case (CMPG, DOUBLE) => jcode.emitDCMPL()
}
- jcode.emitINVOKEVIRTUAL(StringBuilderClassName,
- "append",
- new JMethodType(StringBuilderType,
- Array(jtype)))
- case EndConcat =>
- jcode.emitINVOKEVIRTUAL(StringBuilderClassName,
- "toString",
- toStringType)
- case _ =>
- abort("Unimplemented primitive " + primitive)
+ case Conversion(src, dst) =>
+ debuglog("Converting from: " + src + " to: " + dst)
+ if (dst == BOOL) {
+ println("Illegal conversion at: " + clasz +
+ " at: " + pos.source + ":" + pos.line)
+ } else
+ jcode.emitT2T(javaType(src), javaType(dst))
+
+ case ArrayLength(_) =>
+ jcode.emitARRAYLENGTH()
+
+ case StartConcat =>
+ jcode emitNEW StringBuilderClassName
+ jcode.emitDUP()
+ jcode.emitINVOKESPECIAL(StringBuilderClassName,
+ JMethod.INSTANCE_CONSTRUCTOR_NAME,
+ JMethodType.ARGLESS_VOID_FUNCTION)
+
+ case StringConcat(el) =>
+ val jtype = el match {
+ case REFERENCE(_) | ARRAY(_) => JAVA_LANG_OBJECT
+ case _ => javaType(el)
+ }
+ jcode.emitINVOKEVIRTUAL(StringBuilderClassName,
+ "append",
+ new JMethodType(StringBuilderType,
+ Array(jtype)))
+ case EndConcat =>
+ jcode.emitINVOKEVIRTUAL(StringBuilderClassName,
+ "toString",
+ toStringType)
+
+ case _ =>
+ abort("Unimplemented primitive " + primitive)
+ }
}
- }
// genCode starts here
genBlocks(linearization)