summaryrefslogtreecommitdiff
path: root/src/msil
diff options
context:
space:
mode:
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);