summaryrefslogtreecommitdiff
path: root/sources/scalac/symtab
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2003-07-17 12:15:31 +0000
committerMartin Odersky <odersky@gmail.com>2003-07-17 12:15:31 +0000
commit0c5b3ad66ef8455068ee7f7ad46c08c8b1f5e4d2 (patch)
treef23ccf340c5fb8cad25072c9e2777b4056e6f41b /sources/scalac/symtab
parentb0b2440892e2be86c4e2d77d4406bc9ba72796b0 (diff)
downloadscala-0c5b3ad66ef8455068ee7f7ad46c08c8b1f5e4d2.tar.gz
scala-0c5b3ad66ef8455068ee7f7ad46c08c8b1f5e4d2.tar.bz2
scala-0c5b3ad66ef8455068ee7f7ad46c08c8b1f5e4d2.zip
*** empty log message ***
Diffstat (limited to 'sources/scalac/symtab')
-rw-r--r--sources/scalac/symtab/EntryTags.java37
-rw-r--r--sources/scalac/symtab/Symbol.java7
-rw-r--r--sources/scalac/symtab/Type.java17
-rw-r--r--sources/scalac/symtab/TypeTags.java19
-rw-r--r--sources/scalac/symtab/classfile/ClassParser.java42
-rw-r--r--sources/scalac/symtab/classfile/UnPickle.java386
6 files changed, 459 insertions, 49 deletions
diff --git a/sources/scalac/symtab/EntryTags.java b/sources/scalac/symtab/EntryTags.java
new file mode 100644
index 0000000000..a2e1b32068
--- /dev/null
+++ b/sources/scalac/symtab/EntryTags.java
@@ -0,0 +1,37 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id: EntryTags.java
+
+package scalac.symtab;
+
+public interface EntryTags {
+
+ int TERMname = 1,
+ CONSTRname = 2,
+ TYPEname = 3,
+ NONEsym = 4,
+ TYPEsym = 5,
+ ALIASsym = 6,
+ CLASSsym = 7,
+ MODULEsym = 8,
+ VALsym = 9,
+ EXTsym = 10,
+ NOtpe = 11,
+ THIStpe = 12,
+ SINGLEtpe = 13,
+ TYPEREFtpe = 14,
+ COMPOUNDtpe = 15,
+ METHODtpe = 16,
+ POLYtpe = 17,
+ OVERLOADEDtpe = 18,
+ UNBOXEDtpe = 19,
+ UNBOXEDARRAYtpe = 20,
+ ERRORtpe = 21;
+
+ int firstSymTag = NONEsym, lastSymTag = VALsym;
+ int firstTypeTag = NOtpe, lastTypeTag = UNBOXEDARRAYtpe;
+}
diff --git a/sources/scalac/symtab/Symbol.java b/sources/scalac/symtab/Symbol.java
index 980e11fd01..b8edc68c3b 100644
--- a/sources/scalac/symtab/Symbol.java
+++ b/sources/scalac/symtab/Symbol.java
@@ -1268,13 +1268,6 @@ public class ClassSymbol extends TypeSymbol {
this.mangled = name;
}
- /** Constructor for module classes and classes with static members.
- public ClassSymbol(int pos, Name name, Symbol owner, int flags, Symbol module) {
- this(pos, name, owner, flags);
- this.module = module;
- }
- */
-
/** Constructor for classes to load as source files
*/
public ClassSymbol(Name name, Symbol owner, SourceCompleter parser) {
diff --git a/sources/scalac/symtab/Type.java b/sources/scalac/symtab/Type.java
index eebcd5a865..f9d5823491 100644
--- a/sources/scalac/symtab/Type.java
+++ b/sources/scalac/symtab/Type.java
@@ -15,7 +15,7 @@ import scalac.ApplicationError;
import scalac.util.*;
import scalac.Global;
-public class Type implements Modifiers, Kinds, TypeTags {
+public class Type implements Modifiers, Kinds, TypeTags, EntryTags {
public static boolean explainSwitch = false;
private static int indent = 0;
@@ -2444,7 +2444,7 @@ public class Type implements Modifiers, Kinds, TypeTags {
return THIStpe
^ (sym.hashCode() * 41);
case TypeRef(Type pre, Symbol sym, Type[] args):
- return NAMEDtpe
+ return TYPEREFtpe
^ (pre.hashCode() * 41)
^ (sym.hashCode() * (41*41))
^ (hashCode(args) * (41*41*41));
@@ -2457,7 +2457,10 @@ public class Type implements Modifiers, Kinds, TypeTags {
^ (hashCode(parts) * 41)
^ (members.hashCode() * (41 * 41));
case MethodType(Symbol[] vparams, Type result):
- return METHODtpe
+ int h = METHODtpe;
+ for (int i = 0; i < vparams.length; i++)
+ h = (h << 4) ^ vparams[i].flags;
+ return h
^ (hashCode(Symbol.type(vparams)) * 41)
^ (result.hashCode() * (41 * 41));
case PolyType(Symbol[] tparams, Type result):
@@ -2535,7 +2538,13 @@ public class Type implements Modifiers, Kinds, TypeTags {
case MethodType(Symbol[] vparams, Type result):
switch (that) {
case MethodType(Symbol[] vparams1, Type result1):
- return equals(Symbol.type(vparams), Symbol.type(vparams1)) &&
+ if (vparams.length != vparams1.length)
+ return false;
+ for (int i = 0; i < vparams.length; i++)
+ if (vparams[i].flags != vparams1[i].flags)
+ return false;
+ return
+ equals(Symbol.type(vparams), Symbol.type(vparams1)) &&
result.equals(result1);
default: return false;
}
diff --git a/sources/scalac/symtab/TypeTags.java b/sources/scalac/symtab/TypeTags.java
index a3bd103432..0a0d25cfb6 100644
--- a/sources/scalac/symtab/TypeTags.java
+++ b/sources/scalac/symtab/TypeTags.java
@@ -25,23 +25,4 @@ public interface TypeTags {
int FirstUnboxedTag = BYTE;
int LastUnboxedTag = UNIT;
-
- /** other type tags (used for hashcodes and Pickling)
- */
- int ERRORtpe = 20;
- int NOtpe = 21;
- int THIStpe = 22;
- int NAMEDtpe = 23;
- int SINGLEtpe = 24;
- int COMPOUNDtpe = 25;
- int METHODtpe = 26;
- int POLYtpe = 27;
- int CONSTRUCTORtpe = 28;
- int COVARtpe = 29;
- int OVERLOADEDtpe = 30;
- int UNBOXEDtpe = 31;
- int UNBOXEDARRAYtpe = 32;
-
- int firstTypeTag = ERRORtpe;
- int lastTypeTag = UNBOXEDARRAYtpe;
}
diff --git a/sources/scalac/symtab/classfile/ClassParser.java b/sources/scalac/symtab/classfile/ClassParser.java
index 5ebf85e774..43c0eaff01 100644
--- a/sources/scalac/symtab/classfile/ClassParser.java
+++ b/sources/scalac/symtab/classfile/ClassParser.java
@@ -28,26 +28,30 @@ public class ClassParser extends Type.LazyType {
/** complete class symbol c by loading the class
*/
public void complete(Symbol c) {
- //System.out.println("loading " + c);//DEBUG
- try {
- long msec = System.currentTimeMillis();
- String filename = externalizeFileName(c.fullName()) + ".class";
- AbstractFile f = global.classPath.openFile(filename);
- if (f == null)
- global.error("could not read class " + c);
- else {
- new ClassfileParser(global, new AbstractFileReader(f), c).parse();
- global.operation("loaded " + f.getPath() + " in " +
- (System.currentTimeMillis() - msec) + "ms");
- //for (Definition e = c.locals().elems; e != null; e = e.sibling)
- // if (e.def.kind == TYP)
+ if (completed) {
+ c.setInfo(Type.NoType);
+ } else {
+ //System.out.println("loading " + c);//DEBUG
+ try {
+ long msec = System.currentTimeMillis();
+ String filename = externalizeFileName(c.fullName()) + ".class";
+ AbstractFile f = global.classPath.openFile(filename);
+ if (f == null)
+ global.error("could not read class " + c);
+ else {
+ new ClassfileParser(global, new AbstractFileReader(f), c).parse();
+ global.operation("loaded " + f.getPath() + " in " +
+ (System.currentTimeMillis() - msec) + "ms");
+ //for (Definition e = c.locals().elems; e != null; e = e.sibling)
+ // if (e.def.kind == TYP)
// e.def.complete();
- }
- } catch (IOException e) {
- e.printStackTrace();
- global.error("i/o error while loading " + c);
- c.setInfo(Type.ErrorType);
- }
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ global.error("i/o error while loading " + c);
+ c.setInfo(Type.ErrorType);
+ }
+ }
}
/** return external representation of file name s,
diff --git a/sources/scalac/symtab/classfile/UnPickle.java b/sources/scalac/symtab/classfile/UnPickle.java
new file mode 100644
index 0000000000..eed1fdc00a
--- /dev/null
+++ b/sources/scalac/symtab/classfile/UnPickle.java
@@ -0,0 +1,386 @@
+/* ____ ____ ____ ____ ______ *\
+** / __// __ \/ __// __ \/ ____/ SOcos COmpiles Scala **
+** __\_ \/ /_/ / /__/ /_/ /\_ \ (c) 2002, LAMP/EPFL **
+** /_____/\____/\___/\____/____/ **
+\* */
+
+// $Id$
+
+package scalac.symtab.classfile;
+
+import java.util.HashMap;
+import scalac.*;
+import scalac.util.*;
+import ch.epfl.lamp.util.Position;
+import scalac.symtab.*;
+import Symbol.*;
+import Type.*;
+
+public class UnPickle implements Kinds, Modifiers, EntryTags {
+
+/***************************************************
+ * Symbol table attribute format:
+ * Symtab = nentries_Nat {Entry}
+ * Entry = TERMNAME len_Nat NameInfo
+ * | CONSTRNAME len_Nat NameInfo
+ * | TYPENAME len_Nat NameInfo
+ * | NONEsym len_Nat
+ * | TYPEsym len_Nat SymbolInfo lobound_Ref
+ * | ALIASsym len_Nat SymbolInfo
+ * | CLASSsym len_Nat SymbolInfo thistype_Ref constrsym_Ref
+ * | MODULEsym len_Nat SymbolInfo classsym_Ref
+ * | VALsym len_Nat SymbolInfo [classsym_Ref]
+ * | EXTsym len_Nat name_Ref [owner_Ref]
+ * | NOtpe len_Nat
+ * | THIStpe len_Nat sym_Ref
+ * | SINGLEtpe len_Nat type_Ref sym_Ref
+ * | TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref}
+ * | COMPOUNDtpe len_Nat sym_Ref {tpe_Ref} {sym_Ref}
+ * | METHODtpe len_Nat tpe_Ref {tpe_Ref}
+ * | POLYTtpe len_Nat tpe_Ref {sym_Ref}
+ * | OVERLOADEDtpe len_Nat {sym_Ref} {tpe_Ref}
+ * SymbolInfo = name_Ref owner_Ref flags_Nat info_Ref
+ * NameInfo = <character sequence of length len_Nat in Utf8 format>
+ * Ref = Nat
+ *
+ * len is remaining length after `len'.
+ */
+ static final boolean debug = false;
+
+ Symbol classroot;
+ Symbol moduleroot;
+ byte[] bytes;
+ int bp;
+ Name sourceName;
+ int[] index;
+ Object[] entries;
+
+ UnPickle(Symbol root, byte[] data, Name sourceName) {
+ assert root.rawInfoAt(Symbol.FIRST_ID) instanceof LazyType;
+ //System.out.println("unpickle " + root);//DEBUG
+ this.classroot = root;
+ this.moduleroot = classroot.module();
+ this.bytes = data;
+ this.bp = 0;
+ this.sourceName = sourceName;
+ index = new int[readNat()];
+ for (int i = 0; i < index.length; i++) {
+ index[i] = bp;
+ bp++;
+ bp = readNat() + bp;
+ }
+ entries = new Object[index.length];
+ if (debug) {
+ for (int i = 0; i < index.length; i++) {
+ System.out.print(i + "," + index[i] + ": ");
+ bp = index[i];
+ System.out.print(readByte() + " ");
+ int len = readNat();
+ System.out.print(len + " ");
+ for (int j = 0; j < len; j++)
+ System.out.print(readByte() + " ");
+ System.out.println();
+ }
+ }
+ for (int i = 0; i < index.length; i++) {
+ if (isSymbolEntry(i)) getSymbol(i);
+ }
+ if (root.rawInfoAt(Symbol.FIRST_ID) instanceof LazyType)
+ throw new BadSignature(this, "it does not define " + root);
+ }
+
+ Type setOwner(Type tp, Symbol owner) {
+ switch (tp) {
+ case PolyType(Symbol[] tparams, Type restpe):
+ Type restpe1 = setOwner(restpe, owner);
+ if (restpe1 == restpe) return tp;
+ else return Type.PolyType(tparams, restpe1);
+ case MethodType(Symbol[] params, Type restpe):
+ Symbol[] params1 = params;
+ for (int i = 0; i < params.length; i++) {
+ if (params[i].owner() != owner) {
+ if (params1 == params && params[i].owner() != Symbol.NONE) {
+ params1 = new Symbol[params.length];
+ System.arraycopy(params, 0, params1, 0, i);
+ }
+ params1[i].setOwner(owner);
+ }
+ }
+ Type restpe1 = setOwner(restpe, owner);
+ if (params1 == params && restpe1 == restpe) return tp;
+ else return Type.MethodType(params1, restpe1);
+ default:
+ return tp;
+ }
+ }
+
+ int readByte() {
+ return bytes[bp++];
+ }
+
+ int readNat() {
+ int b;
+ int x = 0;
+ do {
+ b = readByte();
+ x = (x << 7) + (b & 0x7f);
+ } while ((b & 0x80) != 0);
+ return x;
+ }
+
+ boolean isTypeEntry(int i) {
+ int tag = bytes[index[i]];
+ return (firstTypeTag <= tag && tag <= lastTypeTag);
+ }
+
+ boolean isSymbolEntry(int i) {
+ int tag = bytes[index[i]];
+ return (firstSymTag <= tag && tag <= lastSymTag);
+ }
+
+ Name getName(int n) {
+ if (entries[n] == null) {
+ int savedBp = bp;
+ bp = index[n];
+ int tag = bytes[bp++];
+ int len = readNat();
+ Name name = Name.fromAscii(bytes, bp, len);
+ switch (tag) {
+ case TERMname : entries[n] = name; break;
+ case CONSTRname: entries[n] = name.toConstrName(); break;
+ case TYPEname : entries[n] = name.toTypeName(); break;
+ default: throw new BadSignature(this);
+ }
+ bp = savedBp;
+ }
+ return (Name) entries[n];
+ }
+
+ Name readNameRef() {
+ return getName(readNat());
+ }
+
+ Symbol getSymbol(int n) {
+ if (entries[n] == null) {
+ int savedBp = bp;
+ bp = index[n];
+ int tag = bytes[bp++];
+ int end = readNat() + bp;
+ Symbol sym;
+ Symbol owner;
+ switch (tag) {
+ case NONEsym:
+ entries[n] = sym = Symbol.NONE;
+ break;
+ case EXTsym:
+ Name name = readNameRef();
+ if (bp == end) {
+ owner = Global.instance.definitions.ROOT_CLASS;
+ } else {
+ assert bp < end;
+ owner = readSymbolRef();
+ }
+ if (name.length() == 0 && owner == Symbol.NONE) {
+ entries[n] = sym = Global.instance.definitions.ROOT_CLASS;
+ } else {
+ entries[n] = sym = owner.info().lookupNonPrivate(name);
+ }
+ if (sym.kind == NONE) {
+ throw new BadSignature(this,
+ "reference " + name + " of " + owner +
+ " refers to nonexisting symbol.");
+ }
+ break;
+ default:
+ assert isSymbolEntry(n) : n;
+ Name name = readNameRef();
+ owner = readSymbolRef();
+ if (entries[n] == null) {
+ int flags = readNat();
+ int inforef = readNat();
+ switch (tag) {
+ case TYPEsym:
+ entries[n] = sym = new AbsTypeSymbol(
+ Position.NOPOS, name, owner, flags);
+ sym.setInfo(getType(inforef));
+ sym.setLoBound(readTypeRef());
+ break;
+
+ case ALIASsym:
+ entries[n] = sym = new TypeSymbol(
+ ALIAS, Position.NOPOS, name, owner, flags);
+ sym.setInfo(getType(inforef));
+ break;
+
+ case CLASSsym:
+ entries[n] = sym = new ClassSymbol(
+ Position.NOPOS, name, owner, flags);
+ if (name == classroot.name && owner == classroot.owner()) {
+ sym.copyTo(classroot);
+ entries[n] = sym = classroot;
+ }
+ sym.setInfo(getType(inforef));
+ sym.setTypeOfThis(readTypeRef());
+ Symbol constructor = readSymbolRef(); //will install itself!
+ break;
+
+ case MODULEsym:
+ entries[n] = sym = TermSymbol.newModule(
+ Position.NOPOS, name, owner, flags, (ClassSymbol) readSymbolRef());
+ if (name == moduleroot.name && owner == moduleroot.owner()) {
+ sym.copyTo(moduleroot);
+ entries[n] = sym = moduleroot;
+ }
+ sym.setInfo(getType(inforef));
+ break;
+
+ case VALsym:
+ if (bp < end) {
+ assert name.isConstrName();
+ Symbol clazz = readSymbolRef();
+ entries[n] = sym = clazz.constructor();
+ TermSymbol.newConstructor(clazz, flags).copyTo(sym);
+ } else {
+ entries[n] = sym = new TermSymbol(
+ Position.NOPOS, name, owner, flags);
+ }
+ sym.setInfo(setOwner(getType(inforef), sym));
+ break;
+
+ default:
+ throw new BadSignature(this);
+ }
+
+ if (owner.kind == CLASS &&
+ !(sym == classroot ||
+ sym.kind == CLASS && (sym.flags & MODUL) != 0 ||
+ (sym.isPrimaryConstructor() &&
+ (sym.primaryConstructorClass().flags & MODUL) != 0)))
+ owner.members().enter(sym);
+ }
+ }
+ bp = savedBp;
+ }
+ return (Symbol) entries[n];
+ }
+
+ Symbol readSymbolRef() {
+ return getSymbol(readNat());
+ }
+
+ Symbol[] readSymbolRefs(int end) {
+ return readSymbolRefs(0, end);
+ }
+
+ Symbol[] readSymbolRefs(int nread, int end) {
+ if (bp == end) {
+ return new Symbol[nread];
+ } else {
+ assert bp < end;
+ int ref = readNat();
+ if (isSymbolEntry(ref)) {
+ Symbol s = getSymbol(ref);
+ Symbol[] ss = readSymbolRefs(nread+1, end);
+ ss[nread] = s;
+ return ss;
+ } else {
+ return new Symbol[nread];
+ }
+ }
+ }
+
+ Type getType(int n) {
+ if (entries[n] == null) {
+ int savedBp = bp;
+ bp = index[n];
+ int tag = bytes[bp++];
+ int end = readNat() + bp;
+ Type tpe;
+ switch (tag) {
+ case NOtpe:
+ tpe = Type.NoType;
+ break;
+ case THIStpe:
+ tpe = Type.ThisType(readSymbolRef());
+ break;
+ case SINGLEtpe:
+ tpe = Type.singleType(readTypeRef(), readSymbolRef());
+ break;
+ case TYPEREFtpe:
+ tpe = Type.TypeRef(
+ readTypeRef(), readSymbolRef(), readTypeRefs(end));
+ break;
+ case COMPOUNDtpe:
+ Symbol clazz = readSymbolRef();
+ Type[] parents = readTypeRefs(end);
+ Scope members = new Scope(readSymbolRefs(end));
+ tpe = Type.compoundType(parents, members, clazz);
+ break;
+ case METHODtpe:
+ Type restype = readTypeRef();
+ Type[] argtypes = readTypeRefs(end);
+ Symbol[] params = new Symbol[argtypes.length];
+ for (int i = 0; i < argtypes.length; i++) {
+ params[i] = new TermSymbol(
+ Position.NOPOS, Name.fromString("$" + i),
+ Symbol.NONE, PARAM);
+ params[i].setInfo(argtypes[i]);
+ }
+ tpe = Type.MethodType(params, restype);
+ break;
+ case POLYtpe:
+ Type restype = readTypeRef();
+ tpe = Type.PolyType(readSymbolRefs(end), restype);
+ break;
+ case OVERLOADEDtpe:
+ Symbol[] alts = readSymbolRefs(end);
+ Type[] alttypes = readTypeRefs(end);
+ for (int i = 0; i < alts.length; i++)
+ alttypes[i] = setOwner(alttypes[i], alts[i]);
+ tpe = Type.OverloadedType(alts, alttypes);
+ break;
+ default:
+ throw new BadSignature(this);
+ }
+ entries[n] = tpe;
+ bp = savedBp;
+ }
+ return (Type) entries[n];
+ }
+
+ Type readTypeRef() {
+ return getType(readNat());
+ }
+
+ Type[] readTypeRefs(int end) {
+ return readTypeRefs(0, end);
+ }
+
+ Type[] readTypeRefs(int nread, int end) {
+ if (bp == end) {
+ return new Type[nread];
+ } else {
+ assert bp < end;
+ int ref = readNat();
+ if (isTypeEntry(ref)) {
+ Type t = getType(ref);
+ Type[] ts = readTypeRefs(nread + 1, end);
+ ts[nread] = t;
+ return ts;
+ } else {
+ return new Type[nread];
+ }
+ }
+ }
+
+ public static class BadSignature extends java.lang.Error {
+ public BadSignature(UnPickle outer, String msg) {
+ super("symbol data " + outer.sourceName +
+ " could not be loaded; " + msg);
+ }
+ public BadSignature(UnPickle outer) {
+ this(outer, "malformed signature at " + outer.bp);
+ }
+ }
+}
+