diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2006-11-22 18:56:51 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2006-11-22 18:56:51 +0000 |
commit | 5cfd4f2b9e4c285c1936f398d881da80bcb40759 (patch) | |
tree | d2448ce8079e87ada9d0ee96a881232824a83274 | |
parent | 4af77453d44c809c1ac06e78a8b698e2ef28a79d (diff) | |
download | scala-5cfd4f2b9e4c285c1936f398d881da80bcb40759.tar.gz scala-5cfd4f2b9e4c285c1936f398d881da80bcb40759.tar.bz2 scala-5cfd4f2b9e4c285c1936f398d881da80bcb40759.zip |
Fixed even more bugs in icode reader.
5 files changed, 57 insertions, 28 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index 6c46e01af3..4946ed13d8 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -108,14 +108,14 @@ trait BasicBlocks requires ICodes { assert(closed); var i = pos; var d = 0; - while (i > 0 && d >= 0) { + while (i > 0) { i = i - 1; + val prod = instrs(i).produced + if (prod > 0 && d == 0) + return Some(i) d = d + (instrs(i).consumed - instrs(i).produced); } - if (i >= 0) - Some(i) - else - None + None } /** Return the n-th instruction. */ @@ -248,6 +248,10 @@ trait BasicBlocks requires ICodes { } def emit(instr: Instruction, pos: Int) = { + if (closed) { + print(); + Console.println("trying to emit: " + instr) + } assert (!closed || ignore, "BasicBlock closed"); if (!ignore) { @@ -352,8 +356,7 @@ trait BasicBlocks requires ICodes { def print(out: java.io.PrintStream) : unit = { out.println("block #"+label+" :"); - instructionList.reverse.foreach( - (i: Instruction) => out.println(" "+i)); + toList.foreach(i => out.println(" " + i)); out.print("Successors: "); successors.foreach((x: BasicBlock) => out.print(" "+x.label.toString())); out.println(); diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index e5cf77b68b..7e08fedce0 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -156,6 +156,7 @@ trait Members requires ICodes { */ class IMethod(val symbol: Symbol) { var code: Code = null; + var native = false; /** The list of exception handlers, ordered from innermost to outermost. */ var exh: List[ExceptionHandler] = Nil; @@ -205,7 +206,8 @@ trait Members requires ICodes { /** Is this method deferred ('abstract' in Java sense) */ def isDeferred = ( symbol.hasFlag(Flags.DEFERRED) || - symbol.owner.hasFlag(Flags.INTERFACE) + symbol.owner.hasFlag(Flags.INTERFACE) || + native ); def isStatic: Boolean = diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index acf2627466..7937923550 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -228,7 +228,7 @@ abstract class Inliners extends SubComponent { def analyzeClass(cls: IClass): Unit = if (settings.inline.value) { if (settings.debug.value) log("Analyzing " + cls); - cls.methods.foreach { m => analyzeMethod(m) + cls.methods.foreach { m => if (!m.symbol.isConstructor) analyzeMethod(m) }} diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 0cf3714328..72ca5b5b47 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -202,6 +202,7 @@ abstract class ClassfileParser { f = definitions.getModule(name.subName(0, name.length - 1)) } else { val owner = if (static) cls.linkedClassOfClass else cls +// Console.println("" + owner.info.decl(name).tpe + " =:= " + tpe) f = owner.info.decl(name).suchThat(.tpe.=:=(tpe)) if (f == NoSymbol) f = owner.info.decl(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(.tpe.=:=(tpe)) @@ -248,11 +249,13 @@ abstract class ClassfileParser { val start = starts(index) if (in.buf(start) != CONSTANT_CLASS) errorBadTag(start) val name = getExternalName(in.getChar(start + 1)) - if (name(0) == ARRAY_TAG) + if (name(0) == ARRAY_TAG) { c = sigToType(name) - else + values(index) = c + } else { + values(index) = definitions.getClass(name) c = definitions.getClass(name).tpe - values(index) = c + } } else c = value match { case _: Type => value.asInstanceOf[Type] case _: Symbol => value.asInstanceOf[Symbol].tpe diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index d517a8db53..a33d5bb536 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -32,8 +32,8 @@ abstract class ICodeReader extends ClassfileParser { var method: IMethod = _ // the current IMethod val OBJECT: TypeKind = REFERENCE(definitions.ObjectClass) - val nothingName = newTermName("scala.Nothing$") - val nullName = newTermName("scala.Null$") + val nothingName = newTermName("scala.runtime.Nothing$") + val nullName = newTermName("scala.runtime.Null$") var isScalaModule = false /** Read back bytecode for the given class symbol. It returns @@ -50,8 +50,8 @@ abstract class ICodeReader extends ClassfileParser { classFile = cls.asInstanceOf[ClassSymbol].classFile assert(classFile ne null, "No classfile for " + cls) - for (val s <- cls.info.members) - Console.println("" + s + ": " + s.tpe) +// for (val s <- cls.info.members) +// Console.println("" + s + ": " + s.tpe) this.instanceCode = new IClass(cls) this.staticCode = new IClass(cls.linkedClassOfModule) parse(classFile, cls) @@ -120,6 +120,8 @@ abstract class ICodeReader extends ClassfileParser { Console.println("Parsing method " + sym.fullNameString); this.method = new IMethod(sym); getCode(jflags).addMethod(this.method); + if ((jflags & JAVA_ACC_NATIVE) != 0) + this.method.native = true val attributeCount = in.nextChar; for (val i <- 0 until attributeCount) parseAttribute(); @@ -446,7 +448,8 @@ abstract class ICodeReader extends ClassfileParser { val m = pool.getMemberSymbol(in.nextChar, false); size = size + 2; code.emit(CALL_METHOD(m, Dynamic)) case JVM.invokeinterface => - val m = pool.getMemberSymbol(in.nextChar, false); size = size + 2; + val m = pool.getMemberSymbol(in.nextChar, false); size = size + 4; + in.skip(2) code.emit(CALL_METHOD(m, Dynamic)); case JVM.invokespecial => val m = pool.getMemberSymbol(in.nextChar, false); size = size + 2; @@ -536,11 +539,20 @@ abstract class ICodeReader extends ClassfileParser { parseInstruction } - code.toBasicBlock val exceptionEntries = in.nextChar.toInt - in.skip(8 * exceptionEntries) + var i = 0 + while (i < exceptionEntries) { + // skip start end PC + in.skip(4) + // read the handler PC + code.jmpTargets += in.nextChar + // skip the exception type + in.skip(2) + i = i + 1 + } skipAttributes() + code.toBasicBlock //Console.println(code.toString()) } @@ -553,7 +565,7 @@ abstract class ICodeReader extends ClassfileParser { class LinearCode { var instrs: ListBuffer[Pair[Int, Instruction]] = new ListBuffer var jmpTargets: Set[Int] = new HashSet[Int] - var locals: Map[Int, Local] = new HashMap() + var locals: Map[Int, List[Pair[Local, TypeKind]]] = new HashMap() def emit(i: Instruction) = { // Console.println(i); @@ -630,8 +642,8 @@ 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 Some(others) if ((others find { x => x._1 == LONG || x._1 == DOUBLE}) != None) => + error("Illegal index: " + idx + " points in the middle of another local") case _ => () } kind match { @@ -642,14 +654,21 @@ abstract class ICodeReader extends ClassfileParser { } locals.get(idx) match { - case Some(l) => - assert(l.kind == kind, "Expected kind " + - kind + " for local " + l + " but " + l.kind + " found.") - l + case Some(ls) => + val l = ls find { loc => loc._2 == kind } + l match { + case Some(Pair(loc, _)) => loc + case None => + val l = freshLocal(maxLocals + idx, kind, false) + locals(idx) = Pair(l, kind) :: locals(idx) + log("Expected kind " + kind + " for local " + idx + + " but only " + ls + " found. Added new local.") + l + } case None => checkValidIndex val l = freshLocal(idx, kind, false) - locals += idx -> l + locals += idx -> List(Pair(l, kind)) l } } @@ -660,7 +679,9 @@ abstract class ICodeReader extends ClassfileParser { */ def freshLocal(idx: Int, kind: TypeKind, isArg: Boolean) = { val sym = method.symbol.newVariable(NoPos, "loc" + idx).setInfo(kind.toType); - new Local(sym, kind, isArg) + val l = new Local(sym, kind, isArg) + method.addLocal(l) + l } /** Base class for branch instructions that take addresses. */ |