diff options
Diffstat (limited to 'src/msil')
-rw-r--r-- | src/msil/ch/epfl/lamp/compiler/msil/Attribute.java | 191 | ||||
-rw-r--r-- | src/msil/ch/epfl/lamp/compiler/msil/Type.java | 12 | ||||
-rw-r--r-- | src/msil/ch/epfl/lamp/compiler/msil/util/PEStream.java | 2 | ||||
-rw-r--r-- | src/msil/ch/epfl/lamp/compiler/msil/util/Table.java | 4 |
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); |