summaryrefslogtreecommitdiff
path: root/src/msil
diff options
context:
space:
mode:
authorMiguel Garcia <magarcia@epfl.ch>2011-03-28 13:59:16 +0000
committerMiguel Garcia <magarcia@epfl.ch>2011-03-28 13:59:16 +0000
commita1fe9d33bf9f4b14562c50753931673955dcc251 (patch)
tree6e8817b7e8ef00efa7fd9d313cc3c6b2e7422a15 /src/msil
parent1b4fc3f26ea5efbf4784e1eb6d1de38ab1d8b013 (diff)
downloadscala-a1fe9d33bf9f4b14562c50753931673955dcc251.tar.gz
scala-a1fe9d33bf9f4b14562c50753931673955dcc251.tar.bz2
scala-a1fe9d33bf9f4b14562c50753931673955dcc251.zip
(1) The msil library can now parse modreq and m...
(1) The msil library can now parse modreq and modopt, (2) bug fix in GenMSIL. review by rytz. Updated msil.jar coming soon.
Diffstat (limited to 'src/msil')
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/Attribute.java191
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/Type.java12
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java2
-rw-r--r--src/msil/ch/epfl/lamp/compiler/msil/util/Table.java4
4 files changed, 160 insertions, 49 deletions
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Attribute.java b/src/msil/ch/epfl/lamp/compiler/msil/Attribute.java
index aefb6fdaf1..cdcf6a64f1 100644
--- a/src/msil/ch/epfl/lamp/compiler/msil/Attribute.java
+++ b/src/msil/ch/epfl/lamp/compiler/msil/Attribute.java
@@ -108,20 +108,20 @@ public class Attribute {
private static final Map id2type = new HashMap();
static {
map("Boolean", Signature.ELEMENT_TYPE_BOOLEAN);
- map("Char", Signature.ELEMENT_TYPE_CHAR);
- map("SByte", Signature.ELEMENT_TYPE_I1);
- map("Byte", Signature.ELEMENT_TYPE_U1);
- map("Int16", Signature.ELEMENT_TYPE_I2);
- map("UInt16", Signature.ELEMENT_TYPE_U2);
- map("Int32", Signature.ELEMENT_TYPE_I4);
- map("UInt32", Signature.ELEMENT_TYPE_U4);
- map("Int64", Signature.ELEMENT_TYPE_I8);
- map("UInt64", Signature.ELEMENT_TYPE_U8);
- map("Single", Signature.ELEMENT_TYPE_R4);
- map("Double", Signature.ELEMENT_TYPE_R8);
- map("String", Signature.ELEMENT_TYPE_STRING);
- map("Type", Signature.X_ELEMENT_TYPE_TYPE);
- map("Object", Signature.ELEMENT_TYPE_OBJECT);
+ map("Char", Signature.ELEMENT_TYPE_CHAR);
+ map("SByte", Signature.ELEMENT_TYPE_I1);
+ map("Byte", Signature.ELEMENT_TYPE_U1);
+ map("Int16", Signature.ELEMENT_TYPE_I2);
+ map("UInt16", Signature.ELEMENT_TYPE_U2);
+ map("Int32", Signature.ELEMENT_TYPE_I4);
+ map("UInt32", Signature.ELEMENT_TYPE_U4);
+ map("Int64", Signature.ELEMENT_TYPE_I8);
+ map("UInt64", Signature.ELEMENT_TYPE_U8);
+ map("Single", Signature.ELEMENT_TYPE_R4);
+ map("Double", Signature.ELEMENT_TYPE_R8);
+ map("String", Signature.ELEMENT_TYPE_STRING);
+ map("Type", Signature.X_ELEMENT_TYPE_TYPE);
+ map("Object", Signature.ELEMENT_TYPE_OBJECT);
}
private static void map(String type, int id) {
Type t = Type.GetType("System." + type);
@@ -150,42 +150,102 @@ public class Attribute {
private void parseBlob0() {
if (buf != null)
return;
- buf = ByteBuffer.wrap(value);
+ buf = ByteBuffer.wrap(value); // Sec. 23.3 in Partition II of CLR Spec.
buf.order(ByteOrder.LITTLE_ENDIAN);
- short sig = buf.getShort();
+ short sig = buf.getShort(); // Prolog
assert sig == 1 : PEFile.bytes2hex(value);
ParameterInfo[] params = constr.GetParameters();
constrArgs = new Object[params.length];
for (int i = 0; i < params.length; i++) {
- constrArgs[i] = parseElement(params[i].ParameterType);
+ constrArgs[i] = parseFixedArg(params[i].ParameterType); // FixedArg
}
- int ncount = buf.getShort();
+ int ncount = buf.getShort(); // NumNamed
namedArgs = new LinkedHashMap();
for (int i = 0; i < ncount; i++) {
- int designator = buf.get();
+ int designator = buf.get(); // designator one of 0x53 (FIELD) or 0x54 (PROPERTY)
assert designator == Signature.X_ELEMENT_KIND_FIELD
|| designator == Signature.X_ELEMENT_KIND_PROPERTY
: "0x" + PEFile.byte2hex(designator);
- Type type = parseType();
- String name = parseString();
- Object value = parseElement(type);
+ Type type = parseFieldOrPropTypeInNamedArg(); // FieldOrPropType
+ String name = parseString(); // FieldOrPropName
+ Object value = parseFixedArg(type); // FixedArg
NamedArgument narg =
new NamedArgument(designator, name, type, value);
namedArgs.put(name, narg);
}
}
- private Object parseElement(Type type) {
- if (type.IsArray())
+ private Object parseFixedArg(Type type) {
+ if (type.IsArray())
return parseArray(type.GetElementType());
- if (type.IsEnum())
- return parseElement(type.getUnderlyingType());
- return parseElement(getTypeId(type));
+ else
+ return parseElem(type);
+ }
+
+ /* indicates whether the "simple" case (the other is "enum") of the first row
+ in the Elem production should be taken. */
+ private boolean isSimpleElem(Type type) {
+ if(!type2id.containsKey(type)) return false;
+ int id = getTypeId(type);
+ switch(id){
+ case Signature.ELEMENT_TYPE_STRING:
+ case Signature.X_ELEMENT_TYPE_TYPE:
+ case Signature.ELEMENT_TYPE_OBJECT:
+ return false;
+ default:
+ return true;
+ }
}
- private Object parseElement(int id) {
+ /* indicates whether the second row in the Elem production
+ should be taken (and more specifically, "string" case within that row). */
+ private boolean isStringElem(Type type) {
+ if(!type2id.containsKey(type)) return false;
+ int id = getTypeId(type);
+ return id == Signature.ELEMENT_TYPE_STRING;
+ }
+
+ /* indicates whether the second row in the Elem production
+ should be taken (and more specifically, "type" case within that row). */
+ private boolean isTypeElem(Type type) {
+ if(!type2id.containsKey(type)) return false;
+ int id = getTypeId(type);
+ return id == Signature.X_ELEMENT_TYPE_TYPE;
+ }
+
+ /* indicates whether the third row in the Elem production
+ should be taken (and more specifically, "boxed" case within that row). */
+ private boolean isSystemObject(Type type) {
+ if(!type2id.containsKey(type)) return false;
+ int id = getTypeId(type);
+ return id == Signature.ELEMENT_TYPE_OBJECT;
+ }
+
+ private Object parseElem(Type type) {
+ // simple or enum
+ if (isSimpleElem(type)) return parseVal(getTypeId(type));
+ if (type.IsEnum()) return parseVal(getTypeId(type.getUnderlyingType()));
+ // string or type
+ if (isStringElem(type)) return parseString();
+ if (isTypeElem(type)) return getTypeFromSerString();
+ // boxed valuetype, please notice that a "simple" boxed valuetype is preceded by 0x51
+ if (isSystemObject(type)) {
+ Type boxedT = parse0x51();
+ if(boxedT.IsEnum()) {
+ return new BoxedArgument(boxedT, parseVal(getTypeId(boxedT.getUnderlyingType())));
+ } else {
+ return new BoxedArgument(boxedT, parseVal(getTypeId(boxedT))); // TODO dead code?
+ }
+ } else {
+ Type boxedT = parseType();
+ return parseVal(getTypeId(boxedT));
+ }
+ }
+
+ /* this does not parse an Elem, but a made-up production (Element). Don't read too much into this method name! */
+ private Object parseVal(int id) {
switch (id) {
case Signature.ELEMENT_TYPE_BOOLEAN:
return new Boolean(buf.get() == 0 ? false : true);
@@ -193,29 +253,26 @@ public class Attribute {
return new Character(buf.getChar());
case Signature.ELEMENT_TYPE_I1:
case Signature.ELEMENT_TYPE_U1:
- return new Byte(buf.get());
+ return new Byte(buf.get()); // TODO U1 not the same as I1
case Signature.ELEMENT_TYPE_I2:
case Signature.ELEMENT_TYPE_U2:
- return new Short(buf.getShort());
+ return new Short(buf.getShort()); // TODO U2 not the same as I2
case Signature.ELEMENT_TYPE_I4:
case Signature.ELEMENT_TYPE_U4:
- return new Integer(buf.getInt());
+ return new Integer(buf.getInt()); // TODO U4 not the same as I4
case Signature.ELEMENT_TYPE_I8:
case Signature.ELEMENT_TYPE_U8:
- return new Long(buf.getLong());
+ return new Long(buf.getLong()); // TODO U8 not the same as I8
case Signature.ELEMENT_TYPE_R4:
return new Float(buf.getFloat());
case Signature.ELEMENT_TYPE_R8:
return new Double(buf.getDouble());
+ case Signature.X_ELEMENT_TYPE_TYPE:
+ return getTypeFromSerString();
case Signature.ELEMENT_TYPE_STRING:
return parseString();
- case Signature.X_ELEMENT_TYPE_TYPE:
- return getType();
- case Signature.ELEMENT_TYPE_OBJECT:
- Type type = parseType();
- return new BoxedArgument(type, parseElement(type));
default:
- throw new RuntimeException("Unknown type id: " + id);
+ throw new RuntimeException("Shouldn't have called parseVal with: " + id);
}
}
@@ -232,7 +289,7 @@ public class Attribute {
case Signature.ELEMENT_TYPE_CHAR:
return parseCharArray();
case Signature.ELEMENT_TYPE_I1:
- case Signature.ELEMENT_TYPE_U1:
+ case Signature.ELEMENT_TYPE_U1: // TODO U1 not the same as I1
return parseByteArray();
case Signature.ELEMENT_TYPE_I2:
case Signature.ELEMENT_TYPE_U2:
@@ -250,19 +307,61 @@ public class Attribute {
case Signature.ELEMENT_TYPE_STRING:
return parseStringArray();
case Signature.X_ELEMENT_TYPE_ENUM:
- return parseArray(getType());
+ return parseArray(getTypeFromSerString());
default:
throw new RuntimeException("Unknown type id: " + id);
}
}
- private Type parseType() {
+ private Type parseType() { // FieldOrPropType, Sec. 23.3 in Partition II of CLR Spec.
+ int id = buf.get();
+ switch (id) {
+ case Signature.ELEMENT_TYPE_SZARRAY:
+ Type arrT = Type.mkArray(parseType(), 1);
+ return arrT;
+ case Signature.X_ELEMENT_TYPE_ENUM:
+ String enumName = parseString();
+ Type enumT = Type.getType(enumName);
+ return enumT;
+ default:
+ Type t = (Type)id2type.get(new Integer(id));
+ assert t != null : PEFile.byte2hex(id);
+ return t;
+ }
+ }
+
+ private Type parse0x51() {
int id = buf.get();
switch (id) {
+ case 0x51:
+ return parse0x51();
case Signature.ELEMENT_TYPE_SZARRAY:
- return Type.mkArray(parseType(), 1);
+ Type arrT = Type.mkArray(parseType(), 1);
+ return arrT;
+ case Signature.X_ELEMENT_TYPE_ENUM:
+ String enumName = parseString();
+ Type enumT = Type.getType(enumName);
+ return enumT;
+ default:
+ Type t = (Type)id2type.get(new Integer(id));
+ assert t != null : PEFile.byte2hex(id);
+ return t;
+ }
+ }
+
+
+ private Type parseFieldOrPropTypeInNamedArg() { // FieldOrPropType, Sec. 23.3 in Partition II of CLR Spec.
+ int id = buf.get();
+ switch (id) {
+ case 0x51:
+ return (Type)(id2type.get(new Integer(Signature.ELEMENT_TYPE_OBJECT)));
+ // TODO remove case Signature.ELEMENT_TYPE_SZARRAY:
+ // Type arrT = Type.mkArray(parseType(), 1);
+ // return arrT;
case Signature.X_ELEMENT_TYPE_ENUM:
- return getType();
+ String enumName = parseString();
+ Type enumT = Type.getType(enumName); // TODO this "lookup" only covers already-loaded assemblies.
+ return enumT; // TODO null as return value (due to the above) spells trouble later.
default:
Type t = (Type)id2type.get(new Integer(id));
assert t != null : PEFile.byte2hex(id);
@@ -270,7 +369,7 @@ public class Attribute {
}
}
- private Type getType() {
+ private Type getTypeFromSerString() {
String typename = parseString();
int i = typename.indexOf(',');
// fully qualified assembly name follows
@@ -358,7 +457,7 @@ public class Attribute {
return arr;
}
- private String parseString() {
+ private String parseString() { // SerString convention
String str = null;
int length = parseLength();
if (length < 0)
@@ -541,7 +640,7 @@ public class Attribute {
//##########################################################################
- protected static final class BoxedArgument {
+ public static class BoxedArgument {
public final Type type;
public final Object value;
public BoxedArgument(Type type, Object value) {
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/Type.java b/src/msil/ch/epfl/lamp/compiler/msil/Type.java
index b2489ab66e..830632ce45 100644
--- a/src/msil/ch/epfl/lamp/compiler/msil/Type.java
+++ b/src/msil/ch/epfl/lamp/compiler/msil/Type.java
@@ -315,6 +315,18 @@ public abstract class Type extends MemberInfo {
return false;
}
+ public boolean IsNestedType() {
+ return DeclaringType != null;
+ }
+
+ public boolean IsDefinitelyInternal() {
+ if(IsNestedType()) {
+ return IsNestedPrivate();
+ } else {
+ return IsNotPublic();
+ }
+ }
+
//public final boolean IsCOMObject;
//public final boolean IsContextful;
//public final boolean IsMarshalByRef;
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java b/src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java
index ef043875ec..649d9e74f2 100644
--- a/src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java
+++ b/src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java
@@ -152,7 +152,7 @@ public final class PEStream implements Signature {
assert length == 2 : "length == " + length;
return new Character(buffer.getChar());
case ELEMENT_TYPE_I1:
- case ELEMENT_TYPE_U1:
+ case ELEMENT_TYPE_U1: // TODO U1 not the same as I1
assert length == 1;
return new Byte(buffer.get());
case ELEMENT_TYPE_I2:
diff --git a/src/msil/ch/epfl/lamp/compiler/msil/util/Table.java b/src/msil/ch/epfl/lamp/compiler/msil/util/Table.java
index 119d9e6ba3..1f43b8c2fa 100644
--- a/src/msil/ch/epfl/lamp/compiler/msil/util/Table.java
+++ b/src/msil/ch/epfl/lamp/compiler/msil/util/Table.java
@@ -1615,7 +1615,7 @@ public abstract class Table {
public int Number;
public int Flags;
- public int Owner; // a TypeOrMethodDef (§24.2.6) coded index
+ public int Owner; // a TypeOrMethodDef (Sec 24.2.6) coded index
public int Name; // a non-null index into the String heap
private java.util.Map /*<Integer, java.util.Set<Integer>>*/ GenericParamIdxesForMethodDefIdx =
@@ -1760,7 +1760,7 @@ public abstract class Table {
public static final int ID = 0x2c;
public int Owner; // an index into the GenericParam table
- public int Constraint; // a TypeDefOrRef (§24.2.6) coded index
+ public int Constraint; // a TypeDefOrRef (Sec 24.2.6) coded index
public GenericParamConstraint(PEFile file, int rows) {
super(file, ID, rows);