diff options
author | michelou <michelou@epfl.ch> | 2006-08-18 10:07:34 +0000 |
---|---|---|
committer | michelou <michelou@epfl.ch> | 2006-08-18 10:07:34 +0000 |
commit | 1e9090374d7d8da26082c38aea7d34745d8a6232 (patch) | |
tree | 6895d74a95368c44e4e7299d7104856844f17904 | |
parent | 80bfcf9e75b7724453fdfd4be4cdf0efed52a5fb (diff) | |
download | scala-1e9090374d7d8da26082c38aea7d34745d8a6232.tar.gz scala-1e9090374d7d8da26082c38aea7d34745d8a6232.tar.bz2 scala-1e9090374d7d8da26082c38aea7d34745d8a6232.zip |
[Cygwin] splitted big match expression into 3 p...
[Cygwin] splitted big match expression into 3 parts in file
ICodeReader.scala
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala | 601 |
1 files changed, 309 insertions, 292 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 6491f4e186..1225c4d0fe 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -1,36 +1,45 @@ -package scala.tools.nsc.symtab.classfile; +/* NSC -- new Scala compiler + * Copyright 2005-2006 LAMP/EPFL + * @author Iulian Dragos + */ +// $Id$ -import scala.tools.nsc._; -import scala.tools.nsc.backend.icode._; -import scala.tools.nsc.util.Position; +package scala.tools.nsc.symtab.classfile -import scala.collection.mutable._; -import ClassfileConstants._ -import scala.tools.nsc.io._; +import java.io.IOException + +import scala.collection.mutable._ +import scala.tools.nsc._ +import scala.tools.nsc.backend.icode._ +import scala.tools.nsc.io._ +import scala.tools.nsc.util.Position +import ClassfileConstants._ import Flags._ -import java.io.IOException; /** ICode reader from Java bytecode. + * + * @author Iulian Dragos + * @version 1.0 */ abstract class ICodeReader extends ClassfileParser { - val global: Global; - import global._; - import icodes._; + val global: Global + import global._ + import icodes._ - var instanceCode: IClass = null; // the ICode class for the current symbol - var staticCode: IClass = null; // the ICode class static members - var method: IMethod = _; // the current IMethod + var instanceCode: IClass = null // the ICode class for the current symbol + var staticCode: IClass = null // the ICode class static members + var method: IMethod = _ // the current IMethod - val OBJECT: TypeKind = REFERENCE(definitions.ObjectClass); + val OBJECT: TypeKind = REFERENCE(definitions.ObjectClass) /** Read back bytecode for the given class symbol. */ def readClass(cls: ClassSymbol): Pair[IClass, IClass] = { - assert(cls.classFile ne null, "No classfile for " + cls); + assert(cls.classFile ne null, "No classfile for " + cls) - this.instanceCode = new IClass(cls); - this.staticCode = new IClass(cls.linkedClassOfModule); - parse(cls.classFile, cls); + this.instanceCode = new IClass(cls) + this.staticCode = new IClass(cls.linkedClassOfModule) + parse(cls.classFile, cls) Pair(staticCode, instanceCode) } @@ -44,24 +53,24 @@ abstract class ICodeReader extends ClassfileParser { if (c != clazz) throw new IOException("class file '" + in.file + "' contains wrong " + clazz) - in.skip(2); // super class - in.skip(2 * in.nextChar); // interfaces - val fieldCount = in.nextChar; + in.skip(2) // super class + in.skip(2 * in.nextChar) // interfaces + val fieldCount = in.nextChar for (val i <- 0 until fieldCount) parseField(); - val methodCount = in.nextChar; + val methodCount = in.nextChar for (val i <- 0 until methodCount) parseMethod(); } override def parseField(): Unit = { - val Pair(jflags, sym) = parseMember(); - getCode(jflags).addField(new IField(sym)); - skipAttributes(); + val Pair(jflags, sym) = parseMember() + getCode(jflags).addField(new IField(sym)) + skipAttributes() } private def parseMember(): Pair[Int, Symbol] = { - val jflags = in.nextChar; - val name = pool.getName(in.nextChar); - var tpe = pool.getType(in.nextChar); + val jflags = in.nextChar + val name = pool.getName(in.nextChar) + var tpe = pool.getType(in.nextChar) if (name == nme.CONSTRUCTOR) tpe match { case MethodType(formals, restpe) => @@ -70,16 +79,18 @@ abstract class ICodeReader extends ClassfileParser { } Console.println(getOwner(jflags).info.decls); - val sym = getOwner(jflags).info.decl(name).suchThat(old => old.tpe =:= tpe); - assert(sym != NoSymbol, "Could not find symbol for " + name + ": " + tpe + " in " + getOwner(jflags)); + val sym = getOwner(jflags).info.decl(name).suchThat(old => old.tpe =:= tpe) + assert(sym != NoSymbol, + "Could not find symbol for " + name + + ": " + tpe + " in " + getOwner(jflags)) Pair(jflags, sym) } override def parseMethod(): Unit = { - val Pair(jflags, sym) = parseMember(); - this.method = new IMethod(sym); - getCode(jflags).addMethod(method); - val attributeCount = in.nextChar; + val Pair(jflags, sym) = parseMember() + this.method = new IMethod(sym) + getCode(jflags).addMethod(method) + val attributeCount = in.nextChar for (val i <- 0 until attributeCount) parseAttribute(); } @@ -89,67 +100,68 @@ abstract class ICodeReader extends ClassfileParser { val attrLen = in.nextInt attrName match { case nme.CodeATTR => - parseByteCode(); + parseByteCode() case _ => in.skip(attrLen) } } - var maxStack: Int = _; - var maxLocals: Int = _; - val JVM = ClassfileConstants; // shorter, uppercase alias for use in case patterns + var maxStack: Int = _ + var maxLocals: Int = _ + val JVM = ClassfileConstants // shorter, uppercase alias for use in case patterns - def toUnsignedByte(b: Byte): Int = b.toInt & 0xff; + def toUnsignedByte(b: Byte): Int = b.toInt & 0xff /** Parse java bytecode into ICode */ def parseByteCode(): Unit = { - maxStack = in.nextChar; - maxLocals = in.nextChar; - val codeLength = in.nextInt; - var pc = 0; - val code = new LinearCode; + maxStack = in.nextChar + maxLocals = in.nextChar + val codeLength = in.nextInt + var pc = 0 + val code = new LinearCode def parseInstruction: Unit = { - import opcodes._; - import code._; - var size = 1; // instruction size + import opcodes._ + import code._ + var size = 1 // instruction size /** Parse 16 bit jump target. */ def parseJumpTarget = { - size = size + 2; - val offset = in.nextChar; - val target = pc + offset; - assert(target >= 0 && target < codeLength, "Illegal jump target: " + target); - target + size = size + 2 + val offset = in.nextChar + val target = pc + offset + assert(target >= 0 && target < codeLength, "Illegal jump target: " + target) + target } /** Parse 32 bit jump target. */ def parseJumpTargetW = { - size = size + 4; - val offset = in.nextInt; - val target = pc + offset; - assert(target >= 0 && target < codeLength, "Illegal jump target: " + target); + size = size + 4 + val offset = in.nextInt + val target = pc + offset + assert(target >= 0 && target < codeLength, "Illegal jump target: " + target) target } - toUnsignedByte(in.nextByte) match { - case JVM.nop => parseInstruction; - case JVM.aconst_null => code.emit(CONSTANT(Constant(null))); - case JVM.iconst_m1 => code.emit(CONSTANT(Constant(-1))); - case JVM.iconst_0 => code.emit(CONSTANT(Constant(0))); - case JVM.iconst_1 => code.emit(CONSTANT(Constant(1))); - case JVM.iconst_2 => code.emit(CONSTANT(Constant(2))); - case JVM.iconst_3 => code.emit(CONSTANT(Constant(3))); - case JVM.iconst_4 => code.emit(CONSTANT(Constant(4))); - case JVM.iconst_5 => code.emit(CONSTANT(Constant(5))); - - case JVM.lconst_0 => code.emit(CONSTANT(Constant(0l))); - case JVM.lconst_1 => code.emit(CONSTANT(Constant(1l))); - case JVM.fconst_0 => code.emit(CONSTANT(Constant(0.0f))); - case JVM.fconst_1 => code.emit(CONSTANT(Constant(1.0f))); - case JVM.fconst_2 => code.emit(CONSTANT(Constant(2.0f))); - case JVM.dconst_0 => code.emit(CONSTANT(Constant(0.0))); - case JVM.dconst_1 => code.emit(CONSTANT(Constant(1.0))); + val instr = toUnsignedByte(in.nextByte) + if (instr < JVM.pop) instr match { + case JVM.nop => parseInstruction + case JVM.aconst_null => code.emit(CONSTANT(Constant(null))) + case JVM.iconst_m1 => code.emit(CONSTANT(Constant(-1))) + case JVM.iconst_0 => code.emit(CONSTANT(Constant(0))) + case JVM.iconst_1 => code.emit(CONSTANT(Constant(1))) + case JVM.iconst_2 => code.emit(CONSTANT(Constant(2))) + case JVM.iconst_3 => code.emit(CONSTANT(Constant(3))) + case JVM.iconst_4 => code.emit(CONSTANT(Constant(4))) + case JVM.iconst_5 => code.emit(CONSTANT(Constant(5))) + + case JVM.lconst_0 => code.emit(CONSTANT(Constant(0l))) + case JVM.lconst_1 => code.emit(CONSTANT(Constant(1l))) + case JVM.fconst_0 => code.emit(CONSTANT(Constant(0.0f))) + case JVM.fconst_1 => code.emit(CONSTANT(Constant(1.0f))) + case JVM.fconst_2 => code.emit(CONSTANT(Constant(2.0f))) + case JVM.dconst_0 => code.emit(CONSTANT(Constant(0.0))) + case JVM.dconst_1 => code.emit(CONSTANT(Constant(1.0))) case JVM.bipush => code.emit(CONSTANT(Constant(in.nextByte))); size = size + 1; case JVM.sipush => code.emit(CONSTANT(Constant(in.nextChar))); size = size + 2; @@ -161,80 +173,81 @@ abstract class ICodeReader extends ClassfileParser { case JVM.fload => code.emit(LOAD_LOCAL(code.getLocal(in.nextByte, FLOAT))); size = size + 1; case JVM.dload => code.emit(LOAD_LOCAL(code.getLocal(in.nextByte, DOUBLE))); size = size + 1; case JVM.aload => - val local = in.nextByte; size = size + 1; + val local = in.nextByte; size = size + 1; if (local == 0 && !method.isStatic) code.emit(THIS(method.symbol.owner)); else code.emit(LOAD_LOCAL(code.getLocal(local, OBJECT))); - case JVM.iload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, INT))); - case JVM.iload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, INT))); - case JVM.iload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, INT))); - case JVM.iload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, INT))); - case JVM.lload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, LONG))); - case JVM.lload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, LONG))); - case JVM.lload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, LONG))); - case JVM.lload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, LONG))); - case JVM.fload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, FLOAT))); - case JVM.fload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, FLOAT))); - case JVM.fload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, FLOAT))); - case JVM.fload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, FLOAT))); - case JVM.dload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, DOUBLE))); - case JVM.dload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, DOUBLE))); - case JVM.dload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, DOUBLE))); - case JVM.dload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, DOUBLE))); + case JVM.iload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, INT))) + case JVM.iload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, INT))) + case JVM.iload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, INT))) + case JVM.iload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, INT))) + case JVM.lload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, LONG))) + case JVM.lload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, LONG))) + case JVM.lload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, LONG))) + case JVM.lload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, LONG))) + case JVM.fload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, FLOAT))) + case JVM.fload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, FLOAT))) + case JVM.fload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, FLOAT))) + case JVM.fload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, FLOAT))) + case JVM.dload_0 => code.emit(LOAD_LOCAL(code.getLocal(0, DOUBLE))) + case JVM.dload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, DOUBLE))) + case JVM.dload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, DOUBLE))) + case JVM.dload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, DOUBLE))) case JVM.aload_0 => if (!method.isStatic) code.emit(THIS(method.symbol.owner)); else code.emit(LOAD_LOCAL(code.getLocal(0, OBJECT))); - case JVM.aload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, OBJECT))); - case JVM.aload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, OBJECT))); - case JVM.aload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, OBJECT))); - - case JVM.iaload => code.emit(LOAD_ARRAY_ITEM(INT)); - case JVM.laload => code.emit(LOAD_ARRAY_ITEM(LONG)); - case JVM.faload => code.emit(LOAD_ARRAY_ITEM(FLOAT)); - case JVM.daload => code.emit(LOAD_ARRAY_ITEM(DOUBLE)); - case JVM.aaload => code.emit(LOAD_ARRAY_ITEM(OBJECT)); - case JVM.baload => code.emit(LOAD_ARRAY_ITEM(BYTE)); - case JVM.caload => code.emit(LOAD_ARRAY_ITEM(CHAR)); - case JVM.saload => code.emit(LOAD_ARRAY_ITEM(SHORT)); + case JVM.aload_1 => code.emit(LOAD_LOCAL(code.getLocal(1, OBJECT))) + case JVM.aload_2 => code.emit(LOAD_LOCAL(code.getLocal(2, OBJECT))) + case JVM.aload_3 => code.emit(LOAD_LOCAL(code.getLocal(3, OBJECT))) + + case JVM.iaload => code.emit(LOAD_ARRAY_ITEM(INT)) + case JVM.laload => code.emit(LOAD_ARRAY_ITEM(LONG)) + case JVM.faload => code.emit(LOAD_ARRAY_ITEM(FLOAT)) + case JVM.daload => code.emit(LOAD_ARRAY_ITEM(DOUBLE)) + case JVM.aaload => code.emit(LOAD_ARRAY_ITEM(OBJECT)) + case JVM.baload => code.emit(LOAD_ARRAY_ITEM(BYTE)) + case JVM.caload => code.emit(LOAD_ARRAY_ITEM(CHAR)) + case JVM.saload => code.emit(LOAD_ARRAY_ITEM(SHORT)) case JVM.istore => code.emit(STORE_LOCAL(code.getLocal(in.nextByte, INT))); size = size + 1; case JVM.lstore => code.emit(STORE_LOCAL(code.getLocal(in.nextByte, LONG))); size = size + 1; case JVM.fstore => code.emit(STORE_LOCAL(code.getLocal(in.nextByte, FLOAT))); size = size + 1; case JVM.dstore => code.emit(STORE_LOCAL(code.getLocal(in.nextByte, DOUBLE))); size = size + 1; case JVM.astore => code.emit(STORE_LOCAL(code.getLocal(in.nextByte, OBJECT))); size = size + 1; - case JVM.istore_0 => code.emit(STORE_LOCAL(code.getLocal(0, INT))); - case JVM.istore_1 => code.emit(STORE_LOCAL(code.getLocal(1, INT))); - case JVM.istore_2 => code.emit(STORE_LOCAL(code.getLocal(2, INT))); - case JVM.istore_3 => code.emit(STORE_LOCAL(code.getLocal(3, INT))); - case JVM.lstore_0 => code.emit(STORE_LOCAL(code.getLocal(0, LONG))); - case JVM.lstore_1 => code.emit(STORE_LOCAL(code.getLocal(1, LONG))); - case JVM.lstore_2 => code.emit(STORE_LOCAL(code.getLocal(2, LONG))); - case JVM.lstore_3 => code.emit(STORE_LOCAL(code.getLocal(3, LONG))); - case JVM.fstore_0 => code.emit(STORE_LOCAL(code.getLocal(0, FLOAT))); - case JVM.fstore_1 => code.emit(STORE_LOCAL(code.getLocal(1, FLOAT))); - case JVM.fstore_2 => code.emit(STORE_LOCAL(code.getLocal(2, FLOAT))); - case JVM.fstore_3 => code.emit(STORE_LOCAL(code.getLocal(3, FLOAT))); - case JVM.dstore_0 => code.emit(STORE_LOCAL(code.getLocal(0, DOUBLE))); - case JVM.dstore_1 => code.emit(STORE_LOCAL(code.getLocal(1, DOUBLE))); - case JVM.dstore_2 => code.emit(STORE_LOCAL(code.getLocal(2, DOUBLE))); - case JVM.dstore_3 => code.emit(STORE_LOCAL(code.getLocal(3, DOUBLE))); - case JVM.astore_0 => code.emit(STORE_LOCAL(code.getLocal(0, OBJECT))); - case JVM.astore_1 => code.emit(STORE_LOCAL(code.getLocal(1, OBJECT))); - case JVM.astore_2 => code.emit(STORE_LOCAL(code.getLocal(2, OBJECT))); - case JVM.astore_3 => code.emit(STORE_LOCAL(code.getLocal(3, OBJECT))); - case JVM.iastore => code.emit(STORE_ARRAY_ITEM(INT)); - case JVM.lastore => code.emit(STORE_ARRAY_ITEM(LONG)); - case JVM.fastore => code.emit(STORE_ARRAY_ITEM(FLOAT)); - case JVM.dastore => code.emit(STORE_ARRAY_ITEM(DOUBLE)); - case JVM.aastore => code.emit(STORE_ARRAY_ITEM(OBJECT)); - case JVM.bastore => code.emit(STORE_ARRAY_ITEM(BYTE)); - case JVM.castore => code.emit(STORE_ARRAY_ITEM(CHAR)); - case JVM.sastore => code.emit(STORE_ARRAY_ITEM(SHORT)); - + case JVM.istore_0 => code.emit(STORE_LOCAL(code.getLocal(0, INT))) + case JVM.istore_1 => code.emit(STORE_LOCAL(code.getLocal(1, INT))) + case JVM.istore_2 => code.emit(STORE_LOCAL(code.getLocal(2, INT))) + case JVM.istore_3 => code.emit(STORE_LOCAL(code.getLocal(3, INT))) + case JVM.lstore_0 => code.emit(STORE_LOCAL(code.getLocal(0, LONG))) + case JVM.lstore_1 => code.emit(STORE_LOCAL(code.getLocal(1, LONG))) + case JVM.lstore_2 => code.emit(STORE_LOCAL(code.getLocal(2, LONG))) + case JVM.lstore_3 => code.emit(STORE_LOCAL(code.getLocal(3, LONG))) + case JVM.fstore_0 => code.emit(STORE_LOCAL(code.getLocal(0, FLOAT))) + case JVM.fstore_1 => code.emit(STORE_LOCAL(code.getLocal(1, FLOAT))) + case JVM.fstore_2 => code.emit(STORE_LOCAL(code.getLocal(2, FLOAT))) + case JVM.fstore_3 => code.emit(STORE_LOCAL(code.getLocal(3, FLOAT))) + case JVM.dstore_0 => code.emit(STORE_LOCAL(code.getLocal(0, DOUBLE))) + case JVM.dstore_1 => code.emit(STORE_LOCAL(code.getLocal(1, DOUBLE))) + case JVM.dstore_2 => code.emit(STORE_LOCAL(code.getLocal(2, DOUBLE))) + case JVM.dstore_3 => code.emit(STORE_LOCAL(code.getLocal(3, DOUBLE))) + case JVM.astore_0 => code.emit(STORE_LOCAL(code.getLocal(0, OBJECT))) + case JVM.astore_1 => code.emit(STORE_LOCAL(code.getLocal(1, OBJECT))) + case JVM.astore_2 => code.emit(STORE_LOCAL(code.getLocal(2, OBJECT))) + case JVM.astore_3 => code.emit(STORE_LOCAL(code.getLocal(3, OBJECT))) + case JVM.iastore => code.emit(STORE_ARRAY_ITEM(INT)) + case JVM.lastore => code.emit(STORE_ARRAY_ITEM(LONG)) + case JVM.fastore => code.emit(STORE_ARRAY_ITEM(FLOAT)) + case JVM.dastore => code.emit(STORE_ARRAY_ITEM(DOUBLE)) + case JVM.aastore => code.emit(STORE_ARRAY_ITEM(OBJECT)) + case JVM.bastore => code.emit(STORE_ARRAY_ITEM(BYTE)) + case JVM.castore => code.emit(STORE_ARRAY_ITEM(CHAR)) + case JVM.sastore => code.emit(STORE_ARRAY_ITEM(SHORT)) + } + else if (instr < JVM.goto) instr match { case JVM.pop => code.emit(DROP(INT)); // any 1-word type would do case JVM.pop2 => code.emit(DROP(LONG)); // any 2-word type would do case JVM.dup => code.emit(DUP(OBJECT)); // TODO: Is the kind inside DUP ever needed? @@ -245,156 +258,159 @@ abstract class ICodeReader extends ClassfileParser { case JVM.dup2_x2 => Predef.error("Unsupported JVM bytecode: dup2_x2") case JVM.swap => Predef.error("Unsupported JVM bytecode: swap") - case JVM.iadd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT))); - case JVM.ladd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, LONG))); - case JVM.fadd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, FLOAT))); - case JVM.dadd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, DOUBLE))); - case JVM.isub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, INT))); - case JVM.lsub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, LONG))); - case JVM.fsub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, FLOAT))); - case JVM.dsub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, DOUBLE))); - case JVM.imul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, INT))); - case JVM.lmul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, LONG))); - case JVM.fmul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, FLOAT))); - case JVM.dmul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, DOUBLE))); - case JVM.idiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, INT))); - case JVM.ldiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, LONG))); - case JVM.fdiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, FLOAT))); - case JVM.ddiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, DOUBLE))); - case JVM.irem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, INT))); - case JVM.lrem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, LONG))); - case JVM.frem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, FLOAT))); - case JVM.drem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, DOUBLE))); - - case JVM.ineg => code.emit(CALL_PRIMITIVE(Negation(INT))); - case JVM.lneg => code.emit(CALL_PRIMITIVE(Negation(LONG))); - case JVM.fneg => code.emit(CALL_PRIMITIVE(Negation(FLOAT))); - case JVM.dneg => code.emit(CALL_PRIMITIVE(Negation(DOUBLE))); - - case JVM.ishl => code.emit(CALL_PRIMITIVE(Shift(LSL, INT))); - case JVM.lshl => code.emit(CALL_PRIMITIVE(Shift(LSL, LONG))); - case JVM.ishr => code.emit(CALL_PRIMITIVE(Shift(LSR, INT))); - case JVM.lshr => code.emit(CALL_PRIMITIVE(Shift(LSR, LONG))); - case JVM.iushr => code.emit(CALL_PRIMITIVE(Shift(ASR, INT))); - case JVM.lushr => code.emit(CALL_PRIMITIVE(Shift(ASR, LONG))); - case JVM.iand => code.emit(CALL_PRIMITIVE(Logical(AND, INT))); - case JVM.land => code.emit(CALL_PRIMITIVE(Logical(AND, LONG))); - case JVM.ior => code.emit(CALL_PRIMITIVE(Logical(OR, INT))); - case JVM.lor => code.emit(CALL_PRIMITIVE(Logical(OR, LONG))); - case JVM.ixor => code.emit(CALL_PRIMITIVE(Logical(XOR, INT))); - case JVM.lxor => code.emit(CALL_PRIMITIVE(Logical(XOR, LONG))); + case JVM.iadd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT))) + case JVM.ladd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, LONG))) + case JVM.fadd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, FLOAT))) + case JVM.dadd => code.emit(CALL_PRIMITIVE(Arithmetic(ADD, DOUBLE))) + case JVM.isub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, INT))) + case JVM.lsub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, LONG))) + case JVM.fsub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, FLOAT))) + case JVM.dsub => code.emit(CALL_PRIMITIVE(Arithmetic(SUB, DOUBLE))) + case JVM.imul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, INT))) + case JVM.lmul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, LONG))) + case JVM.fmul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, FLOAT))) + case JVM.dmul => code.emit(CALL_PRIMITIVE(Arithmetic(MUL, DOUBLE))) + case JVM.idiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, INT))) + case JVM.ldiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, LONG))) + case JVM.fdiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, FLOAT))) + case JVM.ddiv => code.emit(CALL_PRIMITIVE(Arithmetic(DIV, DOUBLE))) + case JVM.irem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, INT))) + case JVM.lrem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, LONG))) + case JVM.frem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, FLOAT))) + case JVM.drem => code.emit(CALL_PRIMITIVE(Arithmetic(REM, DOUBLE))) + + case JVM.ineg => code.emit(CALL_PRIMITIVE(Negation(INT))) + case JVM.lneg => code.emit(CALL_PRIMITIVE(Negation(LONG))) + case JVM.fneg => code.emit(CALL_PRIMITIVE(Negation(FLOAT))) + case JVM.dneg => code.emit(CALL_PRIMITIVE(Negation(DOUBLE))) + + case JVM.ishl => code.emit(CALL_PRIMITIVE(Shift(LSL, INT))) + case JVM.lshl => code.emit(CALL_PRIMITIVE(Shift(LSL, LONG))) + case JVM.ishr => code.emit(CALL_PRIMITIVE(Shift(LSR, INT))) + case JVM.lshr => code.emit(CALL_PRIMITIVE(Shift(LSR, LONG))) + case JVM.iushr => code.emit(CALL_PRIMITIVE(Shift(ASR, INT))) + case JVM.lushr => code.emit(CALL_PRIMITIVE(Shift(ASR, LONG))) + case JVM.iand => code.emit(CALL_PRIMITIVE(Logical(AND, INT))) + case JVM.land => code.emit(CALL_PRIMITIVE(Logical(AND, LONG))) + case JVM.ior => code.emit(CALL_PRIMITIVE(Logical(OR, INT))) + case JVM.lor => code.emit(CALL_PRIMITIVE(Logical(OR, LONG))) + case JVM.ixor => code.emit(CALL_PRIMITIVE(Logical(XOR, INT))) + case JVM.lxor => code.emit(CALL_PRIMITIVE(Logical(XOR, LONG))) case JVM.iinc => - size = size + 2; - val local = code.getLocal(in.nextByte, INT); - code.emit(CONSTANT(Constant(in.nextByte))); - code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT))); - code.emit(STORE_LOCAL(local)); - - case JVM.i2l => code.emit(CALL_PRIMITIVE(Conversion(INT, LONG))); - case JVM.i2f => code.emit(CALL_PRIMITIVE(Conversion(INT, FLOAT))); - case JVM.i2d => code.emit(CALL_PRIMITIVE(Conversion(INT, DOUBLE))); - case JVM.l2i => code.emit(CALL_PRIMITIVE(Conversion(LONG, INT))); - case JVM.l2f => code.emit(CALL_PRIMITIVE(Conversion(LONG, FLOAT))); - case JVM.l2d => code.emit(CALL_PRIMITIVE(Conversion(LONG, DOUBLE))); - case JVM.f2i => code.emit(CALL_PRIMITIVE(Conversion(FLOAT, INT))); - case JVM.f2l => code.emit(CALL_PRIMITIVE(Conversion(FLOAT, LONG))); - case JVM.f2d => code.emit(CALL_PRIMITIVE(Conversion(FLOAT, DOUBLE))); - case JVM.d2i => code.emit(CALL_PRIMITIVE(Conversion(DOUBLE, INT))); - case JVM.d2l => code.emit(CALL_PRIMITIVE(Conversion(DOUBLE, LONG))); - case JVM.d2f => code.emit(CALL_PRIMITIVE(Conversion(DOUBLE, FLOAT))); - case JVM.i2b => code.emit(CALL_PRIMITIVE(Conversion(INT, BYTE))); - case JVM.i2c => code.emit(CALL_PRIMITIVE(Conversion(INT, CHAR))); - case JVM.i2s => code.emit(CALL_PRIMITIVE(Conversion(INT, SHORT))); - - case JVM.lcmp => code.emit(CALL_PRIMITIVE(Comparison(CMP, LONG))); - case JVM.fcmpl => code.emit(CALL_PRIMITIVE(Comparison(CMPL, FLOAT))); - case JVM.fcmpg => code.emit(CALL_PRIMITIVE(Comparison(CMPG, FLOAT))); - case JVM.dcmpl => code.emit(CALL_PRIMITIVE(Comparison(CMPL, DOUBLE))); - case JVM.dcmpg => code.emit(CALL_PRIMITIVE(Comparison(CMPG, DOUBLE))); - - case JVM.ifeq => code.emit(LCZJUMP(parseJumpTarget, pc + size, EQ, INT)); - case JVM.ifne => code.emit(LCZJUMP(parseJumpTarget, pc + size, NE, INT)); - case JVM.iflt => code.emit(LCZJUMP(parseJumpTarget, pc + size, LT, INT)); - case JVM.ifge => code.emit(LCZJUMP(parseJumpTarget, pc + size, GE, INT)); - case JVM.ifgt => code.emit(LCZJUMP(parseJumpTarget, pc + size, GT, INT)); - case JVM.ifle => code.emit(LCZJUMP(parseJumpTarget, pc + size, LE, INT)); - - case JVM.if_icmpeq => code.emit(LCJUMP(parseJumpTarget, pc + size, EQ, INT)); - case JVM.if_icmpne => code.emit(LCJUMP(parseJumpTarget, pc + size, NE, INT)); - case JVM.if_icmplt => code.emit(LCJUMP(parseJumpTarget, pc + size, LT, INT)); - case JVM.if_icmpge => code.emit(LCJUMP(parseJumpTarget, pc + size, GE, INT)); - case JVM.if_icmpgt => code.emit(LCJUMP(parseJumpTarget, pc + size, GT, INT)); - case JVM.if_icmple => code.emit(LCJUMP(parseJumpTarget, pc + size, LE, INT)); - case JVM.if_acmpeq => code.emit(LCJUMP(parseJumpTarget, pc + size, EQ, OBJECT)); - case JVM.if_acmpne => code.emit(LCJUMP(parseJumpTarget, pc + size, NE, OBJECT)); - - case JVM.goto => emit(LJUMP(parseJumpTarget)); - case JVM.jsr => Predef.error("Cannot handle jsr/ret"); - case JVM.ret => Predef.error("Cannot handle jsr/ret"); + size = size + 2 + val local = code.getLocal(in.nextByte, INT) + code.emit(CONSTANT(Constant(in.nextByte))) + code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT))) + code.emit(STORE_LOCAL(local)) + + case JVM.i2l => code.emit(CALL_PRIMITIVE(Conversion(INT, LONG))) + case JVM.i2f => code.emit(CALL_PRIMITIVE(Conversion(INT, FLOAT))) + case JVM.i2d => code.emit(CALL_PRIMITIVE(Conversion(INT, DOUBLE))) + case JVM.l2i => code.emit(CALL_PRIMITIVE(Conversion(LONG, INT))) + case JVM.l2f => code.emit(CALL_PRIMITIVE(Conversion(LONG, FLOAT))) + case JVM.l2d => code.emit(CALL_PRIMITIVE(Conversion(LONG, DOUBLE))) + case JVM.f2i => code.emit(CALL_PRIMITIVE(Conversion(FLOAT, INT))) + case JVM.f2l => code.emit(CALL_PRIMITIVE(Conversion(FLOAT, LONG))) + case JVM.f2d => code.emit(CALL_PRIMITIVE(Conversion(FLOAT, DOUBLE))) + case JVM.d2i => code.emit(CALL_PRIMITIVE(Conversion(DOUBLE, INT))) + case JVM.d2l => code.emit(CALL_PRIMITIVE(Conversion(DOUBLE, LONG))) + case JVM.d2f => code.emit(CALL_PRIMITIVE(Conversion(DOUBLE, FLOAT))) + case JVM.i2b => code.emit(CALL_PRIMITIVE(Conversion(INT, BYTE))) + case JVM.i2c => code.emit(CALL_PRIMITIVE(Conversion(INT, CHAR))) + case JVM.i2s => code.emit(CALL_PRIMITIVE(Conversion(INT, SHORT))) + + case JVM.lcmp => code.emit(CALL_PRIMITIVE(Comparison(CMP, LONG))) + case JVM.fcmpl => code.emit(CALL_PRIMITIVE(Comparison(CMPL, FLOAT))) + case JVM.fcmpg => code.emit(CALL_PRIMITIVE(Comparison(CMPG, FLOAT))) + case JVM.dcmpl => code.emit(CALL_PRIMITIVE(Comparison(CMPL, DOUBLE))) + case JVM.dcmpg => code.emit(CALL_PRIMITIVE(Comparison(CMPG, DOUBLE))) + + case JVM.ifeq => code.emit(LCZJUMP(parseJumpTarget, pc + size, EQ, INT)) + case JVM.ifne => code.emit(LCZJUMP(parseJumpTarget, pc + size, NE, INT)) + case JVM.iflt => code.emit(LCZJUMP(parseJumpTarget, pc + size, LT, INT)) + case JVM.ifge => code.emit(LCZJUMP(parseJumpTarget, pc + size, GE, INT)) + case JVM.ifgt => code.emit(LCZJUMP(parseJumpTarget, pc + size, GT, INT)) + case JVM.ifle => code.emit(LCZJUMP(parseJumpTarget, pc + size, LE, INT)) + + case JVM.if_icmpeq => code.emit(LCJUMP(parseJumpTarget, pc + size, EQ, INT)) + case JVM.if_icmpne => code.emit(LCJUMP(parseJumpTarget, pc + size, NE, INT)) + case JVM.if_icmplt => code.emit(LCJUMP(parseJumpTarget, pc + size, LT, INT)) + case JVM.if_icmpge => code.emit(LCJUMP(parseJumpTarget, pc + size, GE, INT)) + case JVM.if_icmpgt => code.emit(LCJUMP(parseJumpTarget, pc + size, GT, INT)) + case JVM.if_icmple => code.emit(LCJUMP(parseJumpTarget, pc + size, LE, INT)) + case JVM.if_acmpeq => code.emit(LCJUMP(parseJumpTarget, pc + size, EQ, OBJECT)) + case JVM.if_acmpne => code.emit(LCJUMP(parseJumpTarget, pc + size, NE, OBJECT)) + } + else instr match { + case JVM.goto => emit(LJUMP(parseJumpTarget)) + case JVM.jsr => Predef.error("Cannot handle jsr/ret") + case JVM.ret => Predef.error("Cannot handle jsr/ret") case JVM.tableswitch => var byte1 = in.nextByte; size = size + 1; while (byte1 == 0) { byte1 = in.nextByte; size = size + 1; } val default = byte1 << 24 | in.nextByte << 16 | in.nextByte << 8 | in.nextByte; - size = size + 3; - val low = in.nextInt; - val high = in.nextInt; - size = size + 8; - assert(low <= high, "Value low not <= high for tableswitch."); + size = size + 3 + val low = in.nextInt + val high = in.nextInt + size = size + 8 + assert(low <= high, "Value low not <= high for tableswitch.") - val tags = List.tabulate(high - low + 1, n => List(low + n)); - val targets = for (val _ <- tags) yield parseJumpTargetW; - code.emit(LSWITCH(tags, targets ::: List(default))); + val tags = List.tabulate(high - low + 1, n => List(low + n)) + val targets = for (val _ <- tags) yield parseJumpTargetW + code.emit(LSWITCH(tags, targets ::: List(default))) case JVM.lookupswitch => var byte1 = in.nextByte; size = size + 1; while (byte1 == 0) { byte1 = in.nextByte; size = size + 1; } val default = byte1 << 24 | in.nextByte << 16 | in.nextByte << 8 | in.nextByte; - size = size + 3; - val npairs = in.nextInt; size = size + 4; - var tags: List[List[Int]] = Nil; - var targets: List[Int] = Nil; - var i = 0; + size = size + 3 + val npairs = in.nextInt; size = size + 4 + var tags: List[List[Int]] = Nil + var targets: List[Int] = Nil + var i = 0 while (i < npairs) { tags = List(in.nextInt) :: tags; size = size + 4; targets = parseJumpTargetW :: targets; // parseJumpTargetW updates 'size' itself i = i + 1; } - targets = default :: targets; - code.emit(LSWITCH(tags.reverse, targets.reverse)); + targets = default :: targets + code.emit(LSWITCH(tags.reverse, targets.reverse)) - case JVM.ireturn => code.emit(RETURN(INT)); - case JVM.lreturn => code.emit(RETURN(LONG)); - case JVM.freturn => code.emit(RETURN(FLOAT)); - case JVM.dreturn => code.emit(RETURN(DOUBLE)); - case JVM.areturn => code.emit(RETURN(OBJECT)); - case JVM.return_ => code.emit(RETURN(UNIT)); + case JVM.ireturn => code.emit(RETURN(INT)) + case JVM.lreturn => code.emit(RETURN(LONG)) + case JVM.freturn => code.emit(RETURN(FLOAT)) + case JVM.dreturn => code.emit(RETURN(DOUBLE)) + case JVM.areturn => code.emit(RETURN(OBJECT)) + case JVM.return_ => code.emit(RETURN(UNIT)) case JVM.gestatic => val field = pool.getMemberSymbol(in.nextChar, true); size = size + 2; - code.emit(LOAD_FIELD(field, true)); + code.emit(LOAD_FIELD(field, true)) case JVM.putstatic => val field = pool.getMemberSymbol(in.nextChar, true); size = size + 2; - code.emit(STORE_FIELD(field, true)); + code.emit(STORE_FIELD(field, true)) case JVM.getfield => val field = pool.getMemberSymbol(in.nextChar, false); size = size + 2; - code.emit(LOAD_FIELD(field, false)); + code.emit(LOAD_FIELD(field, false)) case JVM.putfield => val field = pool.getMemberSymbol(in.nextChar, false); size = size + 2; - code.emit(STORE_FIELD(field, false)); + code.emit(STORE_FIELD(field, false)) case JVM.invokevirtual | JVM.invokeinterface => val m = pool.getMemberSymbol(in.nextChar, false); size = size + 2; - code.emit(CALL_METHOD(m, Dynamic)); + code.emit(CALL_METHOD(m, Dynamic)) case JVM.invokespecial => val m = pool.getMemberSymbol(in.nextChar, false); size = size + 2; val style = if (m.name == nme.CONSTRUCTOR || m.hasFlag(Flags.PRIVATE)) Static(true) else SuperCall(m.owner.name); - code.emit(CALL_METHOD(m, style)); + code.emit(CALL_METHOD(m, style)) case JVM.invokestatic => val m = pool.getMemberSymbol(in.nextChar, false); size = size + 2; - code.emit(CALL_METHOD(m, Static(false))); + code.emit(CALL_METHOD(m, Static(false))) - case JVM.new_ => code.emit(NEW(REFERENCE(pool.getClassSymbol(in.nextChar)))); size = size + 2; + case JVM.new_ => + code.emit(NEW(REFERENCE(pool.getClassSymbol(in.nextChar)))) + size = size + 2 case JVM.newarray => val kind = in.nextByte match { case T_BOOLEAN => BOOL @@ -406,12 +422,12 @@ abstract class ICodeReader extends ClassfileParser { case T_INT => INT case T_LONG => LONG } - size = size + 1; - code.emit(CREATE_ARRAY(kind)); + size = size + 1 + code.emit(CREATE_ARRAY(kind)) case JVM.anewarray => val tpe = toTypeKind(pool.getType(in.nextChar)); size = size + 2; - code.emit(CREATE_ARRAY(tpe)); + code.emit(CREATE_ARRAY(tpe)) case JVM.arraylength => code.emit(CALL_PRIMITIVE(ArrayLength(OBJECT))); // the kind does not matter case JVM.athrow => code.emit(THROW()); @@ -432,56 +448,56 @@ abstract class ICodeReader extends ClassfileParser { case JVM.fstore => code.emit(STORE_LOCAL(code.getLocal(in.nextChar, FLOAT))); size = size + 2; case JVM.dstore => code.emit(STORE_LOCAL(code.getLocal(in.nextChar, DOUBLE))); size = size + 2; case JVM.astore => code.emit(STORE_LOCAL(code.getLocal(in.nextChar, OBJECT))); size = size + 2; - case JVM.ret => Predef.error("Cannot handle jsr/ret"); + case JVM.ret => Predef.error("Cannot handle jsr/ret") case JVM.iinc => - size = size + 4; - val local = code.getLocal(in.nextChar, INT); - code.emit(CONSTANT(Constant(in.nextChar))); - code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT))); - code.emit(STORE_LOCAL(local)); - case _ => Predef.error("Invalid 'wide' operand"); + size = size + 4 + val local = code.getLocal(in.nextChar, INT) + code.emit(CONSTANT(Constant(in.nextChar))) + code.emit(CALL_PRIMITIVE(Arithmetic(ADD, INT))) + code.emit(STORE_LOCAL(local)) + case _ => Predef.error("Invalid 'wide' operand") } case JVM.multianewarray => - size = size + 3; - val tpe = toTypeKind(pool.getType(in.nextChar)); - val dim = in.nextByte; - assert(dim == 1, "Cannot handle multidimensional arrays yet."); - code.emit(CREATE_ARRAY(tpe)); + size = size + 3 + val tpe = toTypeKind(pool.getType(in.nextChar)) + val dim = in.nextByte + assert(dim == 1, "Cannot handle multidimensional arrays yet.") + code.emit(CREATE_ARRAY(tpe)) - case JVM.ifnull => code.emit(LCZJUMP(parseJumpTarget, pc + size, EQ, OBJECT)); - case JVM.ifnonnull => code.emit(LCZJUMP(parseJumpTarget, pc + size, NE, OBJECT)); - case JVM.goto_w => code.emit(LJUMP(parseJumpTargetW)); - case JVM.jsr_w => Predef.error("Cannot handle jsr/ret"); + case JVM.ifnull => code.emit(LCZJUMP(parseJumpTarget, pc + size, EQ, OBJECT)) + case JVM.ifnonnull => code.emit(LCZJUMP(parseJumpTarget, pc + size, NE, OBJECT)) + case JVM.goto_w => code.emit(LJUMP(parseJumpTargetW)) + case JVM.jsr_w => Predef.error("Cannot handle jsr/ret") case _ => Predef.error("Unknown bytecode") } - pc = pc + size; + pc = pc + size } while (pc < codeLength) { - parseInstruction; + parseInstruction } - val exceptionEntries = in.nextChar; - in.skip(8 * exceptionEntries); - skipAttributes(); + val exceptionEntries = in.nextChar + in.skip(8 * exceptionEntries) + skipAttributes() - Console.println(code.toString()); + Console.println(code.toString()) } /** Return the icode class that should include members with the given flags. * There are two possible classes, the static part and the instance part. */ def getCode(flags: Int): IClass = - if ((flags & JAVA_ACC_STATIC) != 0) staticCode else instanceCode; + if ((flags & JAVA_ACC_STATIC) != 0) staticCode else instanceCode class LinearCode { - var instrs: ListBuffer[Instruction] = new ListBuffer; - var jmpTargets: Set[Int] = new HashSet[Int]; - var locals: Map[Int, Local] = new HashMap(); + var instrs: ListBuffer[Instruction] = new ListBuffer + var jmpTargets: Set[Int] = new HashSet[Int] + var locals: Map[Int, Local] = new HashMap() - def emit(i: Instruction) = instrs += i; + def emit(i: Instruction) = instrs += i /** Return the local at given index, with the given type. */ def getLocal(idx: Int, kind: TypeKind): Local = { @@ -490,42 +506,43 @@ abstract class ICodeReader extends ClassfileParser { def checkValidIndex: Unit = { locals.get(idx - 1) match { case Some(other) if (other.kind == LONG || other.kind == DOUBLE) => - error("Illegal index: " + idx + " points in the middle of " + other); - case _ => (); + error("Illegal index: " + idx + " points in the middle of " + other) + case _ => () } kind match { case LONG | DOUBLE if (locals.isDefinedAt(idx + 1)) => - error("Illegal index: " + idx + " overlaps " + locals(idx + 1)); - case _ => (); + error("Illegal index: " + idx + " overlaps " + locals(idx + 1)) + case _ => () } } locals.get(idx) match { case Some(l) => - assert(l.kind == kind, "Expected kind " + kind + " for local " + l + " but " + l.kind + " found."); + assert(l.kind == kind, "Expected kind " + + kind + " for local " + l + " but " + l.kind + " found.") l case None => - checkValidIndex; - val l = freshLocal(idx, kind); - locals += idx -> l; + checkValidIndex + val l = freshLocal(idx, kind) + locals += idx -> l l } } - override def toString(): String = instrs.toList.mkString("", "\n", ""); + override def toString(): String = instrs.toList.mkString("", "\n", "") /** Return a fresh Local variable. * TODO: 'isArgument' is always false, should be modified accordingly. */ def freshLocal(idx: Int, kind: TypeKind) = { val sym = method.symbol.newVariable(Position.NOPOS, "loc" + idx).setInfo(kind.toType); - new Local(sym, kind, false); + new Local(sym, kind, false) } /** Base class for branch instructions that take addresses. */ abstract class LazyJump(pc: Int) extends Instruction { - override def toString() = "LazyJump " + pc; - jmpTargets += pc; + override def toString() = "LazyJump " + pc + jmpTargets += pc } case class LJUMP(pc: Int) extends LazyJump(pc); @@ -533,20 +550,20 @@ abstract class ICodeReader extends ClassfileParser { extends LazyJump(success) { override def toString(): String ="LCJUMP (" + kind + ") " + success + " : " + failure; - jmpTargets += failure; + jmpTargets += failure } case class LCZJUMP(success: Int, failure: Int, cond: TestOp, kind: TypeKind) extends LazyJump(success) { override def toString(): String ="LCZJUMP (" + kind + ") " + success + " : " + failure; - jmpTargets += failure; + jmpTargets += failure } case class LSWITCH(tags: List[List[Int]], targets: List[Int]) extends LazyJump(targets.head) { override def toString(): String ="LSWITCH (tags: " + tags + ") targets: " + targets; - targets.tail.foreach(t => jmpTargets += t); + targets.tail.foreach(t => jmpTargets += t) } } } |