summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-09-15 17:31:31 +0000
committerMartin Odersky <odersky@gmail.com>2011-09-15 17:31:31 +0000
commit09b1a31309c9cbf1394c317b87d2073d39a8cd56 (patch)
tree38a72ae94778e32fb2889a9fc2eb04424d6c41ee /src
parent17c04628617809b9542f7d3c9bcb8d3c6d23a2ec (diff)
downloadscala-09b1a31309c9cbf1394c317b87d2073d39a8cd56.tar.gz
scala-09b1a31309c9cbf1394c317b87d2073d39a8cd56.tar.bz2
scala-09b1a31309c9cbf1394c317b87d2073d39a8cd56.zip
Fixed stackoverflow problem when initializing l...
Fixed stackoverflow problem when initializing large scopes.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/internal/Scopes.scala40
1 files changed, 27 insertions, 13 deletions
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala
index a73b0f4b4f..7893e0eb3a 100644
--- a/src/compiler/scala/reflect/internal/Scopes.scala
+++ b/src/compiler/scala/reflect/internal/Scopes.scala
@@ -94,15 +94,18 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
*
* @param e ...
*/
- def enter(e: ScopeEntry) {
+ protected def enter(e: ScopeEntry) {
elemsCache = null
- if (hashtable ne null) {
- val i = e.sym.name.start & HASHMASK
- elems.tail = hashtable(i)
- hashtable(i) = elems
- } else if (size >= MIN_HASH) {
+ if (hashtable ne null)
+ enterInHash(e)
+ else if (size >= MIN_HASH)
createHash()
- }
+ }
+
+ private def enterInHash(e: ScopeEntry): Unit = {
+ val i = e.sym.name.start & HASHMASK
+ e.tail = hashtable(i)
+ hashtable(i) = e
}
/** enter a symbol
@@ -122,15 +125,23 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
private def createHash() {
hashtable = new Array[ScopeEntry](HASHSIZE)
- enterInHash(elems)
+ enterAllInHash(elems)
}
- private def enterInHash(e: ScopeEntry) {
+ private def enterAllInHash(e: ScopeEntry, n: Int = 0) {
if (e ne null) {
- enterInHash(e.next)
- val i = e.sym.name.start & HASHMASK
- e.tail = hashtable(i)
- hashtable(i) = e
+ if (n < maxRecursions) {
+ enterAllInHash(e.next, n + 1)
+ enterInHash(e)
+ } else {
+ var entries: List[ScopeEntry] = List()
+ var ee = e
+ while (ee ne null) {
+ entries = ee :: entries
+ ee = ee.next
+ }
+ entries foreach enterInHash
+ }
}
}
@@ -334,5 +345,8 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
/** The error scope.
*/
class ErrorScope(owner: Symbol) extends Scope(null: ScopeEntry)
+
+ private final val maxRecursions = 1000
+
}