summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2006-11-22 18:56:51 +0000
committerIulian Dragos <jaguarul@gmail.com>2006-11-22 18:56:51 +0000
commit5cfd4f2b9e4c285c1936f398d881da80bcb40759 (patch)
treed2448ce8079e87ada9d0ee96a881232824a83274 /src
parent4af77453d44c809c1ac06e78a8b698e2ef28a79d (diff)
downloadscala-5cfd4f2b9e4c285c1936f398d881da80bcb40759.tar.gz
scala-5cfd4f2b9e4c285c1936f398d881da80bcb40759.tar.bz2
scala-5cfd4f2b9e4c285c1936f398d881da80bcb40759.zip
Fixed even more bugs in icode reader.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala17
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala9
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala53
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. */