Skip to content

Commit 0beca4b

Browse files
committed
Merge pull request scala#3383 from adriaanm/merge-2.10.x
Merge 2.10.x
2 parents 9bc6876 + eca51c4 commit 0beca4b

File tree

31 files changed

+231
-28
lines changed

31 files changed

+231
-28
lines changed

src/asm/scala/tools/asm/MethodWriter.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1869,7 +1869,12 @@ final int getSize() {
18691869
int size = 8;
18701870
if (code.length > 0) {
18711871
if (code.length > 65536) {
1872-
throw new RuntimeException("Method code too large!");
1872+
String nameString = "";
1873+
int i = 0;
1874+
// find item that corresponds to the index of our name
1875+
while (i < cw.items.length && (cw.items[i] == null || cw.items[i].index != name)) i++;
1876+
if (cw.items[i] != null) nameString = cw.items[i].strVal1 +"'s ";
1877+
throw new RuntimeException("Method "+ nameString +"code too large!");
18731878
}
18741879
cw.newUTF8("Code");
18751880
size += 18 + code.length + 8 * handlerCount;

src/compiler/scala/tools/nsc/ast/parser/Parsers.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1030,7 +1030,11 @@ self =>
10301030

10311031
/** Assumed (provisionally) to be TermNames. */
10321032
def ident(skipIt: Boolean): Name = (
1033-
if (isIdent) rawIdent().encode
1033+
if (isIdent) {
1034+
val name = in.name.encode
1035+
in.nextToken()
1036+
name
1037+
}
10341038
else syntaxErrorOrIncompleteAnd(expectedMsg(IDENTIFIER), skipIt)(nme.ERROR)
10351039
)
10361040

src/compiler/scala/tools/nsc/ast/parser/Scanners.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -607,10 +607,7 @@ trait Scanners extends ScannersCommon {
607607
if (ch == '`') {
608608
nextChar()
609609
finishNamed(BACKQUOTED_IDENT)
610-
if (name.length == 0)
611-
syntaxError("empty quoted identifier")
612-
else if (name == nme.WILDCARD)
613-
syntaxError("wildcard invalid as backquoted identifier")
610+
if (name.length == 0) syntaxError("empty quoted identifier")
614611
}
615612
else syntaxError("unclosed quoted identifier")
616613
}

src/compiler/scala/tools/nsc/backend/icode/GenICode.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -793,10 +793,7 @@ abstract class GenICode extends SubComponent {
793793
case _ =>
794794
}
795795
ctx1.bb.emit(cm, tree.pos)
796-
797-
if (sym == ctx1.method.symbol) {
798-
ctx1.method.recursive = true
799-
}
796+
ctx1.method.updateRecursive(sym)
800797
generatedType =
801798
if (sym.isClassConstructor) UNIT
802799
else toTypeKind(sym.info.resultType)

src/compiler/scala/tools/nsc/backend/icode/Members.scala

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ trait Members {
195195
this
196196
}
197197

198+
final def updateRecursive(called: Symbol): Unit = {
199+
recursive ||= (called == symbol)
200+
}
201+
198202
def addLocal(l: Local): Local = findOrElse(locals)(_ == l) { locals ::= l ; l }
199203

200204
def addParam(p: Local): Unit =

src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,9 +469,9 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
469469
}
470470
bytecodeWriter.writeClass(label, jclassName, arr, outF)
471471
} catch {
472-
case e: java.lang.RuntimeException if(e.getMessage() == "Class file too large!") =>
473-
// TODO check where ASM throws the equivalent of CodeSizeTooBigException
474-
log("Skipped class "+jclassName+" because it exceeds JVM limits (it's too big or has methods that are too long).")
472+
case e: java.lang.RuntimeException if e != null && (e.getMessage contains "too large!") =>
473+
reporter.error(sym.pos,
474+
s"Could not write class $jclassName because it exceeds JVM code size limits. ${e.getMessage}")
475475
}
476476
}
477477

src/compiler/scala/tools/nsc/symtab/BrowsingLoaders.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ abstract class BrowsingLoaders extends GlobalSymbolLoaders {
6464
addPackagePrefix(pre)
6565
packagePrefix += ("." + name)
6666
case Ident(name) =>
67-
if (packagePrefix.length != 0) packagePrefix += "."
68-
packagePrefix += name
67+
if (name != nme.EMPTY_PACKAGE_NAME) { // mirrors logic in Namers, see createPackageSymbol
68+
if (packagePrefix.length != 0) packagePrefix += "."
69+
packagePrefix += name
70+
}
6971
case _ =>
7072
throw new MalformedInput(pkg.pos.point, "illegal tree node in package prefix: "+pkg)
7173
}

src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,23 +575,28 @@ abstract class ICodeReader extends ClassfileParser {
575575
case JVM.invokevirtual =>
576576
val m = pool.getMemberSymbol(u2, static = false); size += 2
577577
code.emit(CALL_METHOD(m, Dynamic))
578+
method.updateRecursive(m)
578579
case JVM.invokeinterface =>
579580
val m = pool.getMemberSymbol(u2, static = false); size += 4
580581
in.skip(2)
581582
code.emit(CALL_METHOD(m, Dynamic))
583+
// invokeinterface can't be recursive
582584
case JVM.invokespecial =>
583585
val m = pool.getMemberSymbol(u2, static = false); size += 2
584586
val style = if (m.name == nme.CONSTRUCTOR || m.isPrivate) Static(onInstance = true)
585587
else SuperCall(m.owner.name)
586588
code.emit(CALL_METHOD(m, style))
589+
method.updateRecursive(m)
587590
case JVM.invokestatic =>
588591
val m = pool.getMemberSymbol(u2, static = true); size += 2
589592
if (isBox(m))
590593
code.emit(BOX(toTypeKind(m.info.paramTypes.head)))
591594
else if (isUnbox(m))
592595
code.emit(UNBOX(toTypeKind(m.info.resultType)))
593-
else
596+
else {
594597
code.emit(CALL_METHOD(m, Static(onInstance = false)))
598+
method.updateRecursive(m)
599+
}
595600
case JVM.invokedynamic =>
596601
// TODO, this is just a place holder. A real implementation must parse the class constant entry
597602
debuglog("Found JVM invokedynamic instructionm, inserting place holder ICode INVOKE_DYNAMIC.")

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3326,6 +3326,28 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
33263326
// calls to the default getters. Example:
33273327
// foo[Int](a)() ==> foo[Int](a)(b = foo$qual.foo$default$2[Int](a))
33283328
checkNotMacro()
3329+
3330+
// SI-8111 transformNamedApplication eagerly shuffles around the application to preserve
3331+
// evaluation order. During this process, it calls `changeOwner` on symbols that
3332+
// are transplanted underneath synthetic temporary vals.
3333+
//
3334+
// Here, we keep track of the symbols owned by `context.owner` to enable us to
3335+
// rollback, so that we don't end up with "orphaned" symbols.
3336+
//
3337+
// TODO: Find a better way!
3338+
//
3339+
// Note that duplicating trees would not be enough to fix this problem, we would also need to
3340+
// clone local symbols in the duplicated tree to truly isolate things (in the spirit of BodyDuplicator),
3341+
// or, better yet, disentangle the logic in `transformNamedApplication` so that we could
3342+
// determine whether names/defaults is viable *before* transforming trees.
3343+
def ownerOf(sym: Symbol) = if (sym == null || sym == NoSymbol) NoSymbol else sym.owner
3344+
val symsOwnedByContextOwner = tree.collect {
3345+
case t @ (_: DefTree | _: Function) if ownerOf(t.symbol) == context.owner => t.symbol
3346+
}
3347+
def rollbackNamesDefaultsOwnerChanges() {
3348+
symsOwnedByContextOwner foreach (_.owner = context.owner)
3349+
}
3350+
33293351
val fun1 = transformNamedApplication(Typer.this, mode, pt)(fun, x => x)
33303352
if (fun1.isErroneous) duplErrTree
33313353
else {
@@ -3354,6 +3376,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
33543376
if (!(context.diagnostic contains note)) context.diagnostic = note :: context.diagnostic
33553377
doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt)
33563378
} else {
3379+
rollbackNamesDefaultsOwnerChanges()
33573380
tryTupleApply orElse duplErrorTree(NotEnoughArgsError(tree, fun, missing))
33583381
}
33593382
}

test/files/neg/t6426.check

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)