object ReadValue(SerializationType etype, DmdType argType, out DmdType realArgType) { if (!IncrementRecursionCounter()) throw new CABlobParserException("Stack overflow"); object result; switch (etype) { case SerializationType.Boolean: realArgType = module.AppDomain.System_Boolean; result = reader.ReadByte() != 0; break; case SerializationType.Char: realArgType = module.AppDomain.System_Char; result = (char)reader.ReadUInt16(); break; case SerializationType.I1: realArgType = module.AppDomain.System_SByte; result = reader.ReadSByte(); break; case SerializationType.U1: realArgType = module.AppDomain.System_Byte; result = reader.ReadByte(); break; case SerializationType.I2: realArgType = module.AppDomain.System_Int16; result = reader.ReadInt16(); break; case SerializationType.U2: realArgType = module.AppDomain.System_UInt16; result = reader.ReadUInt16(); break; case SerializationType.I4: realArgType = module.AppDomain.System_Int32; result = reader.ReadInt32(); break; case SerializationType.U4: realArgType = module.AppDomain.System_UInt32; result = reader.ReadUInt32(); break; case SerializationType.I8: realArgType = module.AppDomain.System_Int64; result = reader.ReadInt64(); break; case SerializationType.U8: realArgType = module.AppDomain.System_UInt64; result = reader.ReadUInt64(); break; case SerializationType.R4: realArgType = module.AppDomain.System_Single; result = reader.ReadSingle(); break; case SerializationType.R8: realArgType = module.AppDomain.System_Double; result = reader.ReadDouble(); break; case SerializationType.String: realArgType = module.AppDomain.System_String; result = ReadUTF8String(); break; // It's ET.ValueType if it's eg. a ctor enum arg type case (SerializationType)DMD.ElementType.ValueType: if ((object)argType == null) throw new CABlobParserException("Invalid element type"); realArgType = argType; result = ReadEnumValue(GetEnumUnderlyingType(argType)); break; // It's ET.Object if it's a ctor object arg type case (SerializationType)DMD.ElementType.Object: case SerializationType.TaggedObject: realArgType = ReadFieldOrPropType(); if (realArgType.IsSZArray) result = ReadArrayArgument(realArgType); else result = ReadValue(ToSerializationType(realArgType), realArgType, out var tmpType); break; // It's ET.Class if it's eg. a ctor System.Type arg type case (SerializationType)DMD.ElementType.Class: if (argType == module.AppDomain.System_Type) { result = ReadValue(SerializationType.Type, argType, out realArgType); break; } else if (argType == module.AppDomain.System_String) { result = ReadValue(SerializationType.String, argType, out realArgType); break; } else if (argType == module.AppDomain.System_Object) { result = ReadValue(SerializationType.TaggedObject, argType, out realArgType); break; } // Assume it's an enum that couldn't be resolved realArgType = argType; result = ReadEnumValue(null); break; case SerializationType.Type: realArgType = argType; result = ReadType(true); break; case SerializationType.Enum: realArgType = ReadType(false); result = ReadEnumValue(GetEnumUnderlyingType(realArgType)); break; default: throw new CABlobParserException("Invalid element type"); } DecrementRecursionCounter(); return result; }
bool ReadHeader(out int localSignatureMetadataToken, out int maxStackSize, out bool initLocals, out int codeSize, out bool hasExceptionHandlers) { byte b = reader.ReadByte(); switch (b & 7) { case 2: case 6: localSignatureMetadataToken = 0; maxStackSize = 8; initLocals = false; codeSize = b >> 2; hasExceptionHandlers = false; return(true); case 3: uint flags = (ushort)((reader.ReadByte() << 8) | b); int headerSize = (int)(flags >> 12); initLocals = (flags & 0x10) != 0; maxStackSize = reader.ReadUInt16(); codeSize = reader.ReadInt32(); localSignatureMetadataToken = reader.ReadInt32(); hasExceptionHandlers = (flags & 8) != 0; reader.Position += -12 + headerSize * 4; if (headerSize < 3) { hasExceptionHandlers = false; } return(true); default: localSignatureMetadataToken = 0; maxStackSize = 0; initLocals = false; codeSize = 0; hasExceptionHandlers = false; return(false); } }