예제 #1
0
		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;
		}
예제 #2
0
        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);
            }
        }