diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2010-04-13 22:51:04 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2010-04-13 22:51:04 +0000 |
commit | d95eb2a8f979b9f9db98a0e097ef3793674e57ab (patch) | |
tree | 6e11ba6e02cdd30c53861d42e6e52d5ce34b8d95 /src/compiler | |
parent | c272bbfb64b1d0522e09daa0981a4942f63607a4 (diff) | |
download | scala-d95eb2a8f979b9f9db98a0e097ef3793674e57ab.tar.gz scala-d95eb2a8f979b9f9db98a0e097ef3793674e57ab.tar.bz2 scala-d95eb2a8f979b9f9db98a0e097ef3793674e57ab.zip |
Made the icode reader more resilient to errors.
symbol does not cause any crashes, but the method using an unknown
symbol will not be used for inlining. Resurrected tests, removed
spec-matrix for the moment. No review.
Diffstat (limited to 'src/compiler')
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 23 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala | 82 |
2 files changed, 66 insertions, 39 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 3a8d93a7a7..c78664bc19 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -221,9 +221,14 @@ abstract class ClassfileParser { val ownerTpe = getClassOrArrayType(in.getChar(start + 1)) if (settings.debug.value) log("getMemberSymbol(static: " + static + "): owner type: " + ownerTpe + " " + ownerTpe.typeSymbol.originalName) - val (name, tpe) = getNameAndType(in.getChar(start + 3), ownerTpe) + val (name0, tpe0) = getNameAndType(in.getChar(start + 3), ownerTpe) if (settings.debug.value) - log("getMemberSymbol: name and tpe: " + name + ": " + tpe) + log("getMemberSymbol: name and tpe: " + name0 + ": " + tpe0) + + forceMangledName(tpe0.typeSymbol.name, false) + val (name, tpe) = getNameAndType(in.getChar(start + 3), ownerTpe) +// println("new tpe: " + tpe + " at phase: " + phase) + if (name == nme.MODULE_INSTANCE_FIELD) { val index = in.getChar(start + 1) val name = getExternalName(in.getChar(starts(index) + 1)) @@ -240,9 +245,10 @@ abstract class ClassfileParser { f = owner.info.member(newTermName(origName.toString + nme.LOCAL_SUFFIX)).suchThat(_.tpe =:= tpe) if (f == NoSymbol) { // if it's an impl class, try to find it's static member inside the class - if (ownerTpe.typeSymbol.isImplClass) + if (ownerTpe.typeSymbol.isImplClass) { +// println("impl class, member: " + owner.tpe.member(origName) + ": " + owner.tpe.member(origName).tpe) f = ownerTpe.member(origName).suchThat(_.tpe =:= tpe) - else { + } else { log("Couldn't find " + name + ": " + tpe + " inside: \n" + ownerTpe) f = if (tpe.isInstanceOf[MethodType]) owner.newMethod(owner.pos, name).setInfo(tpe) else owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE) @@ -384,11 +390,14 @@ abstract class ClassfileParser { * flatten would not lift classes that were not referenced in the source code. */ def forceMangledName(name: Name, module: Boolean): Symbol = { - val parts = name.toString.split(Array('.', '$')) + val parts = name.decode.toString.split(Array('.', '$')) var sym: Symbol = definitions.RootClass atPhase(currentRun.flattenPhase.prev) { - for (part0 <- parts; val part = newTermName(part0)) { - val sym1 = sym.info.decl(part.encode)//.suchThat(module == _.isModule) + for (part0 <- parts; if !(part0 == ""); val part = newTermName(part0)) { + val sym1 = atPhase(currentRun.icodePhase) { + sym.linkedClassOfClass.info + sym.info.decl(part.encode) + }//.suchThat(module == _.isModule) if (sym1 == NoSymbol) sym = sym.info.decl(part.encode.toTypeName) else diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 92dfb3749a..e129737ebd 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -99,26 +99,34 @@ abstract class ICodeReader extends ClassfileParser { val owner = getOwner(jflags) val dummySym = owner.newMethod(owner.pos, name).setFlag(javaToScalaFlags(jflags)) - var tpe = pool.getType(dummySym, in.nextChar) - - if ("<clinit>" == name.toString) - (jflags, NoSymbol) - else { - val owner = getOwner(jflags) - var sym = owner.info.member(name).suchThat(old => sameType(old.tpe, tpe)); - if (sym == NoSymbol) - sym = owner.info.member(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(old => old.tpe =:= tpe); - if (sym == NoSymbol) { - log("Could not find symbol for " + name + ": " + tpe + " in " + owner.info.decls) - log(owner.info.member(name).tpe + " : " + tpe) - if (field) - sym = owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE | javaToScalaFlags(jflags)) - else - sym = dummySym.setInfo(tpe) - owner.info.decls.enter(sym) - log("added " + sym + ": " + sym.tpe) + try { + val ch = in.nextChar + var tpe = pool.getType(dummySym, ch) + + if ("<clinit>" == name.toString) + (jflags, NoSymbol) + else { + val owner = getOwner(jflags) + var sym = owner.info.member(name).suchThat(old => sameType(old.tpe, tpe)); + if (sym == NoSymbol) + sym = owner.info.member(newTermName(name.toString + nme.LOCAL_SUFFIX)).suchThat(old => old.tpe =:= tpe); + if (sym == NoSymbol) { + log("Could not find symbol for " + name + ": " + tpe + " in " + owner.info.decls) + log(owner.info.member(name).tpe + " : " + tpe) + if (name.toString() == "toMap") + tpe = pool.getType(dummySym, ch) + if (field) + sym = owner.newValue(owner.pos, name).setInfo(tpe).setFlag(MUTABLE | javaToScalaFlags(jflags)) + else + sym = dummySym.setInfo(tpe) + owner.info.decls.enter(sym) + log("added " + sym + ": " + sym.tpe) + } + (jflags, sym) } - (jflags, sym) + } catch { + case e: MissingRequirementError => + (jflags, NoSymbol) } } @@ -149,18 +157,25 @@ abstract class ICodeReader extends ClassfileParser { override def parseMethod() { val (jflags, sym) = parseMember(false) - if (sym != NoSymbol) { - log("Parsing method " + sym.fullName + ": " + sym.tpe); - this.method = new IMethod(sym); - this.method.returnType = toTypeKind(sym.tpe.resultType) - getCode(jflags).addMethod(this.method) - if ((jflags & JAVA_ACC_NATIVE) != 0) - this.method.native = true - val attributeCount = in.nextChar - for (i <- 0 until attributeCount) parseAttribute() - } else { - if (settings.debug.value) log("Skipping non-existent method."); - skipAttributes(); + var beginning = in.bp + try { + if (sym != NoSymbol) { + log("Parsing method " + sym.fullName + ": " + sym.tpe); + this.method = new IMethod(sym); + this.method.returnType = toTypeKind(sym.tpe.resultType) + getCode(jflags).addMethod(this.method) + if ((jflags & JAVA_ACC_NATIVE) != 0) + this.method.native = true + val attributeCount = in.nextChar + for (i <- 0 until attributeCount) parseAttribute() + } else { + if (settings.debug.value) log("Skipping non-existent method."); + skipAttributes(); + } + } catch { + case e: MissingRequirementError => + in.bp = beginning; skipAttributes + if (settings.debug.value) log("Skipping non-existent method. " + e.msg); } } @@ -187,12 +202,15 @@ abstract class ICodeReader extends ClassfileParser { definitions.getClass(name) } else if (name.endsWith("$")) { val sym = forceMangledName(name.subName(0, name.length -1).decode, true) +// println("classNameToSymbol: " + name + " sym: " + sym) + if (name.toString == "scala.collection.immutable.Stream$$hash$colon$colon$") + print("") if (sym == NoSymbol) definitions.getModule(name.subName(0, name.length - 1)) else sym } else { forceMangledName(name, false) - definitions.getClass(name) + atPhase(currentRun.flattenPhase.next)(definitions.getClass(name)) } if (sym.isModule) sym.moduleClass |