internal static ByteReader FromBlob(byte[] blobHeap, int blob) { ByteReader br = new ByteReader(blobHeap, blob, 4); int length = br.ReadCompressedUInt(); br.end = br.pos + length; return br; }
internal static FieldSignature ReadSig(ModuleReader module, ByteReader br, IGenericContext context) { if (br.ReadByte() != FIELD) { throw new BadImageFormatException(); } CustomModifiers mods = CustomModifiers.Read(module, br, context); Type fieldType = ReadType(module, br, context); return new FieldSignature(fieldType, mods); }
private static void ExtractResources(ResourceDirectoryEntry root, byte[] buf) { ByteReader br = new ByteReader(buf, 0, buf.Length); while (br.Length >= 32) { br.Align(4); RESOURCEHEADER hdr = new RESOURCEHEADER(br); if (hdr.DataSize != 0) { root[hdr.TYPE][hdr.NAME][new OrdinalOrName(hdr.LanguageId)].Data = ByteBuffer.Wrap(br.ReadBytes(hdr.DataSize)); } } }
internal CustomAttributeData(Assembly asm, ConstructorInfo constructor, ByteReader br) { this.lazyConstructor = constructor; if (br.Length == 0) { // it's legal to have an empty blob lazyConstructorArguments = Empty<CustomAttributeTypedArgument>.Array; lazyNamedArguments = Empty<CustomAttributeNamedArgument>.Array; } else { if (br.ReadUInt16() != 1) { throw new BadImageFormatException(); } lazyConstructorArguments = ReadConstructorArguments(asm, br, constructor); lazyNamedArguments = ReadNamedArguments(asm, br, br.ReadUInt16(), constructor.DeclaringType); } }
private static Type ReadGenericInst(ModuleReader module, ByteReader br, IGenericContext context) { Type type; switch (br.ReadByte()) { case ELEMENT_TYPE_CLASS: type = ReadTypeDefOrRefEncoded(module, br, context).MarkNotValueType(); break; case ELEMENT_TYPE_VALUETYPE: type = ReadTypeDefOrRefEncoded(module, br, context).MarkValueType(); break; default: throw new BadImageFormatException(); } if (!type.__IsMissing && !type.IsGenericTypeDefinition) { throw new BadImageFormatException(); } int genArgCount = br.ReadCompressedInt(); Type[] args = new Type[genArgCount]; Type[][] reqmod = null; Type[][] optmod = null; for (int i = 0; i < genArgCount; i++) { // LAMESPEC the Type production (23.2.12) doesn't include CustomMod* for genericinst, but C++ uses it, the verifier allows it and ildasm also supports it CustomModifiers mods = ReadCustomModifiers(module, br, context); if (mods.required != null || mods.optional != null) { if (reqmod == null) { reqmod = new Type[genArgCount][]; optmod = new Type[genArgCount][]; } reqmod[i] = mods.required; optmod[i] = mods.optional; } args[i] = ReadType(module, br, context); } return GenericTypeInstance.Make(type, args, reqmod, optmod); }
bool DecodeDeclSecurity(StringBuilder sb, IList<CustomAttributeData> list, int level) { try { sb.Append(" = {"); bool first = true; foreach (var sec in list) { if (!first) { sb.Append(','); sb.AppendLine(); sb.Append(' ', level + 14); } first = false; string typeName = sec.Constructor.DeclaringType.AssemblyQualifiedName; if (typeName.EndsWith(", mscorlib", StringComparison.Ordinal)) { typeName = typeName.Substring(0, typeName.Length - 10); } AppendTypeName(sb, sec.Constructor.DeclaringType, typeName, compat != CompatLevel.None); sb.Append(" = {"); byte[] blob = sec.__GetBlob(); // LAMESPEC the count of named arguments is a compressed integer (instead of UInt16 as NumNamed in custom attributes) var br = new ByteReader(blob, 0, blob.Length); int count = br.ReadCompressedInt(); ReadNamedArguments(sb, br, count, 0, compat != CompatLevel.None && count > 1); sb.Append('}'); } sb.Append('}'); return true; } catch (IKVM.Reflection.BadImageFormatException) { return false; } }
private static string ReadString(ByteReader br) { return Encoding.UTF8.GetString(br.ReadBytes(br.ReadCompressedUInt())); }
Type ReadType(ByteReader br, out string typeName) { typeName = br.ReadString(); if (typeName == null) { return null; } if (typeName.Length > 0 && typeName[typeName.Length - 1] == 0) { // there are broken compilers that emit an extra NUL character after the type name typeName = typeName.Substring(0, typeName.Length - 1); } var type = universe.ResolveType(assembly, typeName); if (type != null && type.Assembly == mscorlib) { // we don't want that! type = universe.ResolveType(assembly, type.FullName + ", mscorlib, Version=0.0.0.0"); } return type; }
void ReadNamedArguments(StringBuilder sb, ByteReader br, int named, int level, bool securityCompatHack) { for (int i = 0; i < named; i++) { if (i != 0) { AppendNewLine(sb, level); } byte fieldOrProperty = br.ReadByte(); switch (fieldOrProperty) { case 0x53: sb.Append("field "); break; case 0x54: sb.Append("property "); break; default: throw new IKVM.Reflection.BadImageFormatException(); } string typeName; Type fieldOrPropertyType = ReadFieldOrPropType(sb, br, out typeName); AppendCATypeName(sb, fieldOrPropertyType, typeName, securityCompatHack); sb.Append(' ').Append(QuoteIdentifier(br.ReadString(), true)).Append(" = "); ReadFixedArg(sb, br, fieldOrPropertyType); } }
bool DecodeCABlob(StringBuilder sb, ConstructorInfo constructor, byte[] blob, int level) { try { // CustomAttribute var br = new ByteReader(blob, 2, blob.Length - 4); ReadConstructorArguments(sb, br, constructor, level); br = new ByteReader(blob, blob.Length - (br.Length + 2), br.Length + 2); int named = br.ReadUInt16(); if (constructor.GetParameters().Length != 0 && named != 0) { AppendNewLine(sb, level); } ReadNamedArguments(sb, br, named, level, false); return true; } catch (IKVM.Reflection.BadImageFormatException) { } catch (ArgumentOutOfRangeException) { } return false; }
internal RESOURCEHEADER(ByteReader br) { DataSize = br.ReadInt32(); HeaderSize = br.ReadInt32(); TYPE = ReadOrdinalOrName(br); NAME = ReadOrdinalOrName(br); br.Align(4); DataVersion = br.ReadInt32(); MemoryFlags = br.ReadUInt16(); LanguageId = br.ReadUInt16(); Version = br.ReadInt32(); Characteristics = br.ReadInt32(); }
internal static Type ReadTypeDefOrRefEncoded(ModuleReader module, ByteReader br, IGenericContext context) { int encoded = br.ReadCompressedUInt(); switch (encoded & 3) { case 0: return module.ResolveType((TypeDefTable.Index << 24) + (encoded >> 2), null, null); case 1: return module.ResolveType((TypeRefTable.Index << 24) + (encoded >> 2), null, null); case 2: return module.ResolveType((TypeSpecTable.Index << 24) + (encoded >> 2), context); default: throw new BadImageFormatException(); } }
internal ByteReader GetStandAloneSig(int index) { return(ByteReader.FromBlob(blobHeap, StandAloneSig.records[index])); }
private MemberInfo GetMemberRef(int index, Type[] genericTypeArguments, Type[] genericMethodArguments) { if (memberRefs == null) { memberRefs = new MemberInfo[MemberRef.records.Length]; } if (memberRefs[index] == null) { int owner = MemberRef.records[index].Class; int sig = MemberRef.records[index].Signature; string name = GetString(MemberRef.records[index].Name); switch (owner >> 24) { case MethodDefTable.Index: return(GetMethodAt(null, (owner & 0xFFFFFF) - 1)); case ModuleRefTable.Index: memberRefs[index] = ResolveTypeMemberRef(ResolveModuleType(owner), name, ByteReader.FromBlob(blobHeap, sig)); break; case TypeDefTable.Index: case TypeRefTable.Index: memberRefs[index] = ResolveTypeMemberRef(ResolveType(owner), name, ByteReader.FromBlob(blobHeap, sig)); break; case TypeSpecTable.Index: { Type type = ResolveType(owner, genericTypeArguments, genericMethodArguments); if (type.IsArray) { MethodSignature methodSig = MethodSignature.ReadSig(this, ByteReader.FromBlob(blobHeap, sig), new GenericContext(genericTypeArguments, genericMethodArguments)); return(type.FindMethod(name, methodSig) ?? universe.GetMissingMethodOrThrow(type, name, methodSig)); } else if (type.IsGenericTypeInstance) { MemberInfo member = ResolveTypeMemberRef(type.GetGenericTypeDefinition(), name, ByteReader.FromBlob(blobHeap, sig)); MethodBase mb = member as MethodBase; if (mb != null) { member = mb.BindTypeParameters(type); } FieldInfo fi = member as FieldInfo; if (fi != null) { member = fi.BindTypeParameters(type); } return(member); } else { return(ResolveTypeMemberRef(type, name, ByteReader.FromBlob(blobHeap, sig))); } } default: throw new BadImageFormatException(); } } return(memberRefs[index]); }
internal static MethodSignature ReadSig(ModuleReader module, ByteReader br, IGenericContext context) { CallingConventions callingConvention; int genericParamCount; Type returnType; Type[] parameterTypes; byte flags = br.ReadByte(); switch (flags & 7) { case DEFAULT: callingConvention = CallingConventions.Standard; break; case VARARG: callingConvention = CallingConventions.VarArgs; break; default: throw new BadImageFormatException(); } if ((flags & HASTHIS) != 0) { callingConvention |= CallingConventions.HasThis; } if ((flags & EXPLICITTHIS) != 0) { callingConvention |= CallingConventions.ExplicitThis; } genericParamCount = 0; if ((flags & GENERIC) != 0) { genericParamCount = br.ReadCompressedInt(); context = new UnboundGenericMethodContext(context); } int paramCount = br.ReadCompressedInt(); Type[][][] modifiers = null; Type[] optionalCustomModifiers; Type[] requiredCustomModifiers; ReadCustomModifiers(module, br, context, out requiredCustomModifiers, out optionalCustomModifiers); returnType = ReadRetType(module, br, context); parameterTypes = new Type[paramCount]; PackedCustomModifiers.SetModifiers(ref modifiers, 0, 0, optionalCustomModifiers, paramCount + 1); PackedCustomModifiers.SetModifiers(ref modifiers, 0, 1, requiredCustomModifiers, paramCount + 1); for (int i = 0; i < parameterTypes.Length; i++) { if ((callingConvention & CallingConventions.VarArgs) != 0 && br.PeekByte() == SENTINEL) { Array.Resize(ref parameterTypes, i); if (modifiers != null) { Array.Resize(ref modifiers, i + 1); } break; } ReadCustomModifiers(module, br, context, out requiredCustomModifiers, out optionalCustomModifiers); PackedCustomModifiers.SetModifiers(ref modifiers, i + 1, 0, optionalCustomModifiers, paramCount + 1); PackedCustomModifiers.SetModifiers(ref modifiers, i + 1, 1, requiredCustomModifiers, paramCount + 1); parameterTypes[i] = ReadParam(module, br, context); } return new MethodSignature(returnType, parameterTypes, modifiers, callingConvention, genericParamCount); }
internal static Type ReadTypeSpec(ModuleReader module, ByteReader br, IGenericContext context) { // LAMESPEC a TypeSpec can contain custom modifiers (C++/CLI generates "newarr (TypeSpec with custom modifiers)") CustomModifiers.Skip(br); // LAMESPEC anything can be adorned by (useless) custom modifiers // also, VAR and MVAR are also used in TypeSpec (contrary to what the spec says) return ReadType(module, br, context); }
internal Type ResolveType(int metadataToken, IGenericContext context) { int index = (metadataToken & 0xFFFFFF) - 1; if (index < 0) { throw TokenOutOfRangeException(metadataToken); } else if ((metadataToken >> 24) == TypeDefTable.Index && index < TypeDef.RowCount) { PopulateTypeDef(); return(typeDefs[index]); } else if ((metadataToken >> 24) == TypeRefTable.Index && index < TypeRef.RowCount) { if (typeRefs == null) { typeRefs = new Type[TypeRef.records.Length]; } if (typeRefs[index] == null) { int scope = TypeRef.records[index].ResolutionScope; switch (scope >> 24) { case AssemblyRefTable.Index: { Assembly assembly = ResolveAssemblyRef((scope & 0xFFFFFF) - 1); TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); typeRefs[index] = assembly.ResolveType(typeName); break; } case TypeRefTable.Index: { Type outer = ResolveType(scope, null); TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); typeRefs[index] = outer.ResolveNestedType(typeName); break; } case ModuleTable.Index: case ModuleRefTable.Index: { Module module; if (scope >> 24 == ModuleTable.Index) { if (scope == 0 || scope == 1) { module = this; } else { throw new NotImplementedException("self reference scope?"); } } else { module = ResolveModuleRef(ModuleRef.records[(scope & 0xFFFFFF) - 1]); } TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); typeRefs[index] = module.FindType(typeName) ?? module.universe.GetMissingTypeOrThrow(module, null, typeName); break; } default: throw new NotImplementedException("ResolutionScope = " + scope.ToString("X")); } } return(typeRefs[index]); } else if ((metadataToken >> 24) == TypeSpecTable.Index && index < TypeSpec.RowCount) { if (typeSpecs == null) { typeSpecs = new Type[TypeSpec.records.Length]; } Type type = typeSpecs[index]; if (type == null) { TrackingGenericContext tc = context == null ? null : new TrackingGenericContext(context); type = Signature.ReadTypeSpec(this, ByteReader.FromBlob(blobHeap, TypeSpec.records[index]), tc); if (tc == null || !tc.IsUsed) { typeSpecs[index] = type; } } return(type); } else { throw TokenOutOfRangeException(metadataToken); } }
private static Type ReadFunctionPointer(ModuleReader module, ByteReader br, IGenericContext context) { __StandAloneMethodSig sig = MethodSignature.ReadStandAloneMethodSig(module, br, context); if (module.universe.EnableFunctionPointers) { return FunctionPointerType.Make(module.universe, sig); } else { // by default, like .NET we return System.IntPtr here return module.universe.System_IntPtr; } }
// this reads just the optional parameter types, from a MethodRefSig internal static Type[] ReadOptionalParameterTypes(ModuleReader module, ByteReader br, IGenericContext context, out CustomModifiers[] customModifiers) { br.ReadByte(); int paramCount = br.ReadCompressedUInt(); CustomModifiers.Skip(br); ReadRetType(module, br, context); for (int i = 0; i < paramCount; i++) { if (br.PeekByte() == SENTINEL) { br.ReadByte(); Type[] types = new Type[paramCount - i]; customModifiers = new CustomModifiers[types.Length]; for (int j = 0; j < types.Length; j++) { customModifiers[j] = CustomModifiers.Read(module, br, context); types[j] = ReadType(module, br, context); } return types; } CustomModifiers.Skip(br); ReadType(module, br, context); } customModifiers = Empty<CustomModifiers>.Array; return Type.EmptyTypes; }
internal static Type[] ReadMethodSpec(ModuleReader module, ByteReader br, IGenericContext context) { if (br.ReadByte() != GENERICINST) { throw new BadImageFormatException(); } Type[] args = new Type[br.ReadCompressedUInt()]; for (int i = 0; i < args.Length; i++) { CustomModifiers.Skip(br); args[i] = ReadType(module, br, context); } return args; }
private static OrdinalOrName ReadOrdinalOrName(ByteReader br) { char c = br.ReadChar(); if (c == 0xFFFF) { return new OrdinalOrName(br.ReadUInt16()); } else { StringBuilder sb = new StringBuilder(); while (c != 0) { sb.Append(c); c = br.ReadChar(); } return new OrdinalOrName(sb.ToString()); } }
private static int[] ReadArrayBounds(ByteReader br) { int num = br.ReadCompressedUInt(); if (num == 0) { return null; } int[] arr = new int[num]; for (int i = 0; i < num; i++) { arr[i] = br.ReadCompressedInt(); } return arr; }
void ReadConstructorArguments(StringBuilder sb, ByteReader br, ConstructorInfo constructor, int level) { bool first = true; foreach (var parameter in constructor.GetParameters()) { if (!first) { AppendNewLine(sb, level); } first = false; ReadFixedArg(sb, br, parameter.ParameterType); } }
private static Type ReadTypeOrVoid(ModuleReader module, ByteReader br, IGenericContext context) { if (br.PeekByte() == ELEMENT_TYPE_VOID) { br.ReadByte(); return module.universe.System_Void; } else { return ReadType(module, br, context); } }
void ReadFixedArg(StringBuilder sb, ByteReader br, Type type, bool arrayElement = false) { if (type.IsArray) { int length = br.ReadInt32(); if (length == -1 && compat == CompatLevel.None) { sb.Append("nullref"); } else if (length == 0 && compat != CompatLevel.None) { throw new IKVM.Reflection.BadImageFormatException(); } else { Type elementType = type.GetElementType(); AppendCATypeName(sb, elementType, null); sb.AppendFormat("[{0}](", length); for (int i = 0; i < length; i++) { if (i != 0) { sb.Append(' '); } if (elementType == typeofSystemObject) { string typeName; ReadFixedArg(sb, br, ReadFieldOrPropType(sb, br, out typeName), false); } else { ReadFixedArg(sb, br, elementType, true); } } sb.Append(')'); } } else if (type.FullName == "System.Type" && type.Assembly.GetName().Name == "mscorlib") { if (!arrayElement) { AppendCATypeName(sb, type, null); sb.Append('('); } string typeName; var type1 = ReadType(br, out typeName); if (type1 == null) { if (typeName == null) { sb.Append("nullref"); } else { sb.Append("class ").Append(QuoteIdentifier(typeName, true)); } } else { AppendTypeName(sb, type1, typeName, compat != CompatLevel.None && IsNestedTypeWithNamespace(type1)); } if (!arrayElement) { sb.Append(')'); } } else if (type.Assembly == mscorlib) { if (!arrayElement) { AppendCATypeName(sb, type, null); sb.Append('('); } if (type == typeofSystemBoolean) { sb.Append(br.ReadByte() == 0 ? "false" : "true"); } else if (type == typeofSystemByte) { sb.Append(br.ReadByte()); } else if (type == typeofSystemSByte) { sb.Append(br.ReadSByte()); } else if (type == typeofSystemChar) { sb.AppendFormat("0x{0:X4}", (int)br.ReadChar()); } else if (type == typeofSystemInt16) { sb.Append(br.ReadInt16()); } else if (type == typeofSystemUInt16) { sb.Append(br.ReadUInt16()); } else if (type == typeofSystemInt32) { sb.Append(br.ReadInt32()); } else if (type == typeofSystemUInt32) { sb.Append(br.ReadInt32()); } else if (type == typeofSystemInt64) { sb.Append(br.ReadInt64()); } else if (type == typeofSystemUInt64) { sb.Append(br.ReadInt64()); } else if (type == typeofSystemSingle) { sb.Append(ToString(br.ReadSingle(), true)); } else if (type == typeofSystemDouble) { sb.Append(ToString(br.ReadDouble(), true)); } else if (type == typeofSystemString) { var str = br.ReadString(); if (str == null) { sb.Append("nullref"); } else { if (compat != CompatLevel.None) { int pos = str.IndexOf((char)0); if (pos != -1) { str = str.Substring(0, pos); } } sb.Append(QuoteIdentifier(str, true)); } } else if (type == typeofSystemObject) { string typeName; ReadFixedArg(sb, br, ReadFieldOrPropType(sb, br, out typeName)); } else { throw new NotImplementedException(type.FullName); } if (!arrayElement) { sb.Append(')'); } } else if (type.__IsMissing || (compat != CompatLevel.None && typerefs.Contains(type))) { // ildasm actually tries to load the assembly, but we can't do that, so we cheat by having // a list of 'known' enum types if (type.Assembly.GetName().Name == "mscorlib") { switch (type.FullName) { case "System.AttributeTargets": case "System.Runtime.ConstrainedExecution.Consistency": case "System.Runtime.ConstrainedExecution.Cer": case "System.Security.Permissions.SecurityAction": case "System.Security.Permissions.SecurityPermissionFlag": case "System.Runtime.Versioning.ResourceScope": case "System.Runtime.InteropServices.CallingConvention": case "System.Runtime.InteropServices.CharSet": ReadFixedArg(sb, br, typeofSystemInt32); return; case "System.Security.SecurityRuleSet": if (compat != CompatLevel.V20) { ReadFixedArg(sb, br, typeofSystemByte); return; } break; case "System.Diagnostics.Tracing.EventLevel": case "System.Diagnostics.Tracing.EventTask": case "System.Diagnostics.Tracing.EventOpcode": if (compat != CompatLevel.V20 && compat != CompatLevel.V40) { ReadFixedArg(sb, br, typeofSystemInt32); return; } break; case "System.Type": sb.Append("type("); string typeName; AppendTypeName(sb, ReadType(br, out typeName), typeName); sb.Append(")"); return; } } switch (br.Length) { case 1: if (compat != CompatLevel.None) { // ildasm uses bool (???) as the underlying type in this case sb.AppendFormat("bool({0})", br.ReadByte() == 0 ? "false" : "true"); } else { // just guess that the enum has int8 as the underlying type sb.AppendFormat("int8({0})", br.ReadSByte()); } break; case 2: // just guess that the enum has int16 as the underlying type sb.AppendFormat("int16({0})", br.ReadInt16()); break; case 4: // just guess that the enum has int32 as the underlying type sb.AppendFormat("int32({0})", br.ReadInt32()); break; case 8: // just guess that the enum has int64 as the underlying type sb.AppendFormat("int64({0})", br.ReadInt64()); break; default: throw new IKVM.Reflection.BadImageFormatException(); } } else if (type.IsEnum) { ReadFixedArg(sb, br, type.GetEnumUnderlyingType(), arrayElement); } else { throw new NotImplementedException(type.FullName); } }
// see ECMA 335 CLI spec June 2006 section 23.2.12 for this production protected static Type ReadType(ModuleReader module, ByteReader br, IGenericContext context) { CustomModifiers mods; switch (br.ReadByte()) { case ELEMENT_TYPE_CLASS: return ReadTypeDefOrRefEncoded(module, br, context).MarkNotValueType(); case ELEMENT_TYPE_VALUETYPE: return ReadTypeDefOrRefEncoded(module, br, context).MarkValueType(); case ELEMENT_TYPE_BOOLEAN: return module.universe.System_Boolean; case ELEMENT_TYPE_CHAR: return module.universe.System_Char; case ELEMENT_TYPE_I1: return module.universe.System_SByte; case ELEMENT_TYPE_U1: return module.universe.System_Byte; case ELEMENT_TYPE_I2: return module.universe.System_Int16; case ELEMENT_TYPE_U2: return module.universe.System_UInt16; case ELEMENT_TYPE_I4: return module.universe.System_Int32; case ELEMENT_TYPE_U4: return module.universe.System_UInt32; case ELEMENT_TYPE_I8: return module.universe.System_Int64; case ELEMENT_TYPE_U8: return module.universe.System_UInt64; case ELEMENT_TYPE_R4: return module.universe.System_Single; case ELEMENT_TYPE_R8: return module.universe.System_Double; case ELEMENT_TYPE_I: return module.universe.System_IntPtr; case ELEMENT_TYPE_U: return module.universe.System_UIntPtr; case ELEMENT_TYPE_STRING: return module.universe.System_String; case ELEMENT_TYPE_OBJECT: return module.universe.System_Object; case ELEMENT_TYPE_VAR: return context.GetGenericTypeArgument(br.ReadCompressedUInt()); case ELEMENT_TYPE_MVAR: return context.GetGenericMethodArgument(br.ReadCompressedUInt()); case ELEMENT_TYPE_GENERICINST: return ReadGenericInst(module, br, context); case ELEMENT_TYPE_SZARRAY: mods = CustomModifiers.Read(module, br, context); return ReadType(module, br, context).__MakeArrayType(mods); case ELEMENT_TYPE_ARRAY: mods = CustomModifiers.Read(module, br, context); return ReadType(module, br, context).__MakeArrayType(br.ReadCompressedUInt(), ReadArraySizes(br), ReadArrayBounds(br), mods); case ELEMENT_TYPE_PTR: mods = CustomModifiers.Read(module, br, context); return ReadTypeOrVoid(module, br, context).__MakePointerType(mods); case ELEMENT_TYPE_FNPTR: return ReadFunctionPointer(module, br, context); default: throw new BadImageFormatException(); } }
Type ReadFieldOrPropType(StringBuilder sb, ByteReader br, out string typeName) { const byte ELEMENT_TYPE_BOOLEAN = 0x02; const byte ELEMENT_TYPE_CHAR = 0x03; const byte ELEMENT_TYPE_I1 = 0x04; const byte ELEMENT_TYPE_U1 = 0x05; const byte ELEMENT_TYPE_I2 = 0x06; const byte ELEMENT_TYPE_U2 = 0x07; const byte ELEMENT_TYPE_I4 = 0x08; const byte ELEMENT_TYPE_U4 = 0x09; const byte ELEMENT_TYPE_I8 = 0x0a; const byte ELEMENT_TYPE_U8 = 0x0b; const byte ELEMENT_TYPE_R4 = 0x0c; const byte ELEMENT_TYPE_R8 = 0x0d; const byte ELEMENT_TYPE_STRING = 0x0e; const byte ELEMENT_TYPE_SZARRAY = 0x1d; typeName = null; switch (br.ReadByte()) { case ELEMENT_TYPE_BOOLEAN: return typeofSystemBoolean; case ELEMENT_TYPE_CHAR: return typeofSystemChar; case ELEMENT_TYPE_I1: return typeofSystemSByte; case ELEMENT_TYPE_U1: return typeofSystemByte; case ELEMENT_TYPE_I2: return typeofSystemInt16; case ELEMENT_TYPE_U2: return typeofSystemUInt16; case ELEMENT_TYPE_I4: return typeofSystemInt32; case ELEMENT_TYPE_U4: return typeofSystemUInt32; case ELEMENT_TYPE_I8: return typeofSystemInt64; case ELEMENT_TYPE_U8: return typeofSystemUInt64; case ELEMENT_TYPE_R4: return typeofSystemSingle; case ELEMENT_TYPE_R8: return typeofSystemDouble; case ELEMENT_TYPE_STRING: return typeofSystemString; case ELEMENT_TYPE_SZARRAY: return ReadFieldOrPropType(sb, br, out typeName).MakeArrayType(); case 0x55: return ReadType(br, out typeName); case 0x50: return typeofSystemType; case 0x51: return typeofSystemObject; default: throw new IKVM.Reflection.BadImageFormatException(); } }
internal static void ReadLocalVarSig(ModuleReader module, ByteReader br, IGenericContext context, List<LocalVariableInfo> list) { if (br.Length < 2 || br.ReadByte() != LOCAL_SIG) { throw new BadImageFormatException("Invalid local variable signature"); } int count = br.ReadCompressedUInt(); for (int i = 0; i < count; i++) { if (br.PeekByte() == ELEMENT_TYPE_TYPEDBYREF) { br.ReadByte(); list.Add(new LocalVariableInfo(i, module.universe.System_TypedReference, false, new CustomModifiers())); } else { CustomModifiers mods1 = CustomModifiers.Read(module, br, context); bool pinned = false; if (br.PeekByte() == ELEMENT_TYPE_PINNED) { br.ReadByte(); pinned = true; } CustomModifiers mods2 = CustomModifiers.Read(module, br, context); Type type = ReadTypeOrByRef(module, br, context); list.Add(new LocalVariableInfo(i, type, pinned, CustomModifiers.Combine(mods1, mods2))); } } }
private static Type ReadType(Module module, ByteReader br) { string str = ReadString(br); if (str == "") { return null; } return module.Assembly.GetType(str) ?? module.universe.GetType(str, true); }
private static Type ReadTypeOrByRef(ModuleReader module, ByteReader br, IGenericContext context) { if (br.PeekByte() == ELEMENT_TYPE_BYREF) { br.ReadByte(); // LAMESPEC it is allowed (by C++/CLI, ilasm and peverify) to have custom modifiers after the BYREF // (which makes sense, as it is analogous to pointers) CustomModifiers mods = CustomModifiers.Read(module, br, context); // C++/CLI generates void& local variables, so we need to use ReadTypeOrVoid here return ReadTypeOrVoid(module, br, context).__MakeByRefType(mods); } else { return ReadType(module, br, context); } }
internal static __StandAloneMethodSig ReadStandAloneMethodSig(ModuleReader module, ByteReader br, IGenericContext context) { CallingConventions callingConvention = 0; System.Runtime.InteropServices.CallingConvention unmanagedCallingConvention = 0; bool unmanaged; byte flags = br.ReadByte(); switch (flags & 7) { case DEFAULT: callingConvention = CallingConventions.Standard; unmanaged = false; break; case 0x01: // C unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl; unmanaged = true; break; case 0x02: // STDCALL unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall; unmanaged = true; break; case 0x03: // THISCALL unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.ThisCall; unmanaged = true; break; case 0x04: // FASTCALL unmanagedCallingConvention = System.Runtime.InteropServices.CallingConvention.FastCall; unmanaged = true; break; case VARARG: callingConvention = CallingConventions.VarArgs; unmanaged = false; break; default: throw new BadImageFormatException(); } if ((flags & HASTHIS) != 0) { callingConvention |= CallingConventions.HasThis; } if ((flags & EXPLICITTHIS) != 0) { callingConvention |= CallingConventions.ExplicitThis; } if ((flags & GENERIC) != 0) { throw new BadImageFormatException(); } int paramCount = br.ReadCompressedInt(); SkipCustomModifiers(br); Type returnType = ReadRetType(module, br, context); List<Type> parameterTypes = new List<Type>(); List<Type> optionalParameterTypes = new List<Type>(); List<Type> curr = parameterTypes; for (int i = 0; i < paramCount; i++) { if (br.PeekByte() == SENTINEL) { br.ReadByte(); curr = optionalParameterTypes; } SkipCustomModifiers(br); curr.Add(ReadParam(module, br, context)); } return new __StandAloneMethodSig(unmanaged, unmanagedCallingConvention, callingConvention, returnType, parameterTypes.ToArray(), optionalParameterTypes.ToArray()); }
protected static Type ReadParam(ModuleReader module, ByteReader br, IGenericContext context) { switch (br.PeekByte()) { case ELEMENT_TYPE_TYPEDBYREF: br.ReadByte(); return module.universe.System_TypedReference; default: return ReadTypeOrByRef(module, br, context); } }
private MemberInfo ResolveTypeMemberRef(Type type, string name, ByteReader sig) { if (sig.PeekByte() == Signature.FIELD) { Type org = type; FieldSignature fieldSig = FieldSignature.ReadSig(this, sig, type); FieldInfo field = type.FindField(name, fieldSig); if (field == null && universe.MissingMemberResolution) { return universe.GetMissingFieldOrThrow(this, type, name, fieldSig); } while (field == null && (type = type.BaseType) != null) { field = type.FindField(name, fieldSig); } if (field != null) { return field; } throw new MissingFieldException(org.ToString(), name); } else { Type org = type; MethodSignature methodSig = MethodSignature.ReadSig(this, sig, type); MethodBase method = type.FindMethod(name, methodSig); if (method == null && universe.MissingMemberResolution) { return universe.GetMissingMethodOrThrow(this, type, name, methodSig); } while (method == null && (type = type.BaseType) != null) { method = type.FindMethod(name, methodSig); } if (method != null) { return method; } throw new MissingMethodException(org.ToString(), name); } }
internal override ByteReader GetBlob(int blobIndex) { return(ByteReader.FromBlob(blobHeap, blobIndex)); }