Example #1
0
        internal int Add(ByteBuffer bb)
        {
            Debug.Assert(!frozen);
            int bblen = bb.Length;

            if (bblen == 0)
            {
                return(0);
            }
            int lenlen = MetadataWriter.GetCompressedUIntLength(bblen);
            int hash   = bb.Hash();
            int index  = (hash & 0x7FFFFFFF) % map.Length;

            Key[] keys = map;
            int   last = index;

            while (keys[index].offset != 0)
            {
                if (keys[index].hash == hash &&
                    keys[index].len == bblen &&
                    buf.Match(keys[index].offset + lenlen, bb, 0, bblen))
                {
                    return(keys[index].offset);
                }
                if (index == last)
                {
                    if (keys[index].next == null)
                    {
                        keys[index].next = new Key[4];
                        keys             = keys[index].next;
                        index            = 0;
                        break;
                    }
                    keys  = keys[index].next;
                    index = -1;
                    last  = keys.Length - 1;
                }
                index++;
            }
            int offset = buf.Position;

            buf.WriteCompressedUInt(bblen);
            buf.Write(bb);
            keys[index].len    = bblen;
            keys[index].hash   = hash;
            keys[index].offset = offset;
            return(offset);
        }
		private static void WriteString(ByteBuffer bb, string str)
		{
			byte[] buf = Encoding.UTF8.GetBytes(str);
			bb.WriteCompressedUInt(buf.Length);
			bb.Write(buf);
		}
		private static int WriteMarshallingDescriptor(ModuleBuilder module, CustomAttributeBuilder attribute)
		{
			UnmanagedType unmanagedType;
			object val = attribute.GetConstructorArgument(0);
			if (val is short)
			{
				unmanagedType = (UnmanagedType)(short)val;
			}
			else if (val is int)
			{
				unmanagedType = (UnmanagedType)(int)val;
			}
			else
			{
				unmanagedType = (UnmanagedType)val;
			}

			ByteBuffer bb = new ByteBuffer(5);
			bb.WriteCompressedUInt((int)unmanagedType);

			if (unmanagedType == UnmanagedType.LPArray)
			{
				UnmanagedType arraySubType = attribute.GetFieldValue<UnmanagedType>("ArraySubType") ?? NATIVE_TYPE_MAX;
				bb.WriteCompressedUInt((int)arraySubType);
				int? sizeParamIndex = attribute.GetFieldValue<short>("SizeParamIndex");
				int? sizeConst = attribute.GetFieldValue<int>("SizeConst");
				if (sizeParamIndex != null)
				{
					bb.WriteCompressedUInt(sizeParamIndex.Value);
					if (sizeConst != null)
					{
						bb.WriteCompressedUInt(sizeConst.Value);
						bb.WriteCompressedUInt(1); // flag that says that SizeParamIndex was specified
					}
				}
				else if (sizeConst != null)
				{
					bb.WriteCompressedUInt(0); // SizeParamIndex
					bb.WriteCompressedUInt(sizeConst.Value);
					bb.WriteCompressedUInt(0); // flag that says that SizeParamIndex was not specified
				}
			}
			else if (unmanagedType == UnmanagedType.SafeArray)
			{
				VarEnum? safeArraySubType = attribute.GetFieldValue<VarEnum>("SafeArraySubType");
				if (safeArraySubType != null)
				{
					bb.WriteCompressedUInt((int)safeArraySubType);
					Type safeArrayUserDefinedSubType = (Type)attribute.GetFieldValue("SafeArrayUserDefinedSubType");
					if (safeArrayUserDefinedSubType != null)
					{
						WriteType(module, bb, safeArrayUserDefinedSubType);
					}
				}
			}
			else if (unmanagedType == UnmanagedType.ByValArray)
			{
				bb.WriteCompressedUInt(attribute.GetFieldValue<int>("SizeConst") ?? 1);
				UnmanagedType? arraySubType = attribute.GetFieldValue<UnmanagedType>("ArraySubType");
				if (arraySubType != null)
				{
					bb.WriteCompressedUInt((int)arraySubType);
				}
			}
			else if (unmanagedType == UnmanagedType.ByValTStr)
			{
				bb.WriteCompressedUInt(attribute.GetFieldValue<int>("SizeConst").Value);
			}
			else if (unmanagedType == UnmanagedType.Interface
				|| unmanagedType == UnmanagedType.IDispatch
				|| unmanagedType == UnmanagedType.IUnknown)
			{
				int? iidParameterIndex = attribute.GetFieldValue<int>("IidParameterIndex");
				if (iidParameterIndex != null)
				{
					bb.WriteCompressedUInt(iidParameterIndex.Value);
				}
			}
			else if (unmanagedType == UnmanagedType.CustomMarshaler)
			{
				bb.WriteCompressedUInt(0);
				bb.WriteCompressedUInt(0);
				string marshalType = (string)attribute.GetFieldValue("MarshalType");
				if (marshalType != null)
				{
					WriteString(bb, marshalType);
				}
				else
				{
					WriteType(module, bb, (Type)attribute.GetFieldValue("MarshalTypeRef"));
				}
				WriteString(bb, (string)attribute.GetFieldValue("MarshalCookie") ?? "");
			}

			return module.Blobs.Add(bb);
		}
		internal static void WriteSignatureHelper(ModuleBuilder module, ByteBuffer bb, byte flags, ushort paramCount, List<Type> args)
		{
			bb.Write(flags);
			if (flags != FIELD)
			{
				bb.WriteCompressedUInt(paramCount);
			}
			foreach (Type type in args)
			{
				if (type == null)
				{
					bb.Write(ELEMENT_TYPE_VOID);
				}
				else if (type is MarkerType)
				{
					bb.Write(type.SigElementType);
				}
				else
				{
					WriteType(module, bb, type);
				}
			}
		}
		internal static void WriteMethodSpec(ModuleBuilder module, ByteBuffer bb, Type[] genArgs)
		{
			bb.Write(GENERICINST);
			bb.WriteCompressedUInt(genArgs.Length);
			foreach (Type arg in genArgs)
			{
				WriteType(module, bb, arg);
			}
		}
		internal static void WriteStandAloneMethodSig(ModuleBuilder module, ByteBuffer bb, __StandAloneMethodSig sig)
		{
			if (sig.IsUnmanaged)
			{
				switch (sig.UnmanagedCallingConvention)
				{
					case CallingConvention.Cdecl:
						bb.Write((byte)0x01);	// C
						break;
					case CallingConvention.StdCall:
					case CallingConvention.Winapi:
						bb.Write((byte)0x02);	// STDCALL
						break;
					case CallingConvention.ThisCall:
						bb.Write((byte)0x03);	// THISCALL
						break;
					case CallingConvention.FastCall:
						bb.Write((byte)0x04);	// FASTCALL
						break;
					default:
						throw new ArgumentOutOfRangeException("callingConvention");
				}
			}
			else
			{
				CallingConventions callingConvention = sig.CallingConvention;
				byte flags = 0;
				if ((callingConvention & CallingConventions.HasThis) != 0)
				{
					flags |= HASTHIS;
				}
				if ((callingConvention & CallingConventions.ExplicitThis) != 0)
				{
					flags |= EXPLICITTHIS;
				}
				if ((callingConvention & CallingConventions.VarArgs) != 0)
				{
					flags |= VARARG;
				}
				bb.Write(flags);
			}
			Type[] parameterTypes = sig.ParameterTypes;
			Type[] optionalParameterTypes = sig.OptionalParameterTypes;
			bb.WriteCompressedUInt(parameterTypes.Length + optionalParameterTypes.Length);
			WriteCustomModifiers(module, bb, sig.GetReturnTypeCustomModifiers());
			WriteType(module, bb, sig.ReturnType);
			int index = 0;
			foreach (Type t in parameterTypes)
			{
				WriteCustomModifiers(module, bb, sig.GetParameterCustomModifiers(index++));
				WriteType(module, bb, t);
			}
			// note that optional parameters are only allowed for managed signatures (but we don't enforce that)
			if (optionalParameterTypes.Length > 0)
			{
				bb.Write(SENTINEL);
				foreach (Type t in optionalParameterTypes)
				{
					WriteCustomModifiers(module, bb, sig.GetParameterCustomModifiers(index++));
					WriteType(module, bb, t);
				}
			}
		}
		private static void WriteGenericSignature(ModuleBuilder module, ByteBuffer bb, Type type)
		{
			Type[] typeArguments = type.GetGenericArguments();
			CustomModifiers[] customModifiers = type.__GetGenericArgumentsCustomModifiers();
			if (!type.IsGenericTypeDefinition)
			{
				type = type.GetGenericTypeDefinition();
			}
			bb.Write(ELEMENT_TYPE_GENERICINST);
			if (type.IsValueType)
			{
				bb.Write(ELEMENT_TYPE_VALUETYPE);
			}
			else
			{
				bb.Write(ELEMENT_TYPE_CLASS);
			}
			bb.WriteTypeDefOrRefEncoded(module.GetTypeToken(type).Token);
			bb.WriteCompressedUInt(typeArguments.Length);
			for (int i = 0; i < typeArguments.Length; i++)
			{
				WriteCustomModifiers(module, bb, customModifiers[i]);
				WriteType(module, bb, typeArguments[i]);
			}
		}
		protected static void WriteType(ModuleBuilder module, ByteBuffer bb, Type type)
		{
			while (type.HasElementType)
			{
				byte sigElementType = type.SigElementType;
				bb.Write(sigElementType);
				if (sigElementType == ELEMENT_TYPE_ARRAY)
				{
					// LAMESPEC the Type production (23.2.12) doesn't include CustomMod* for arrays, but the verifier allows it and ildasm also supports it
					WriteCustomModifiers(module, bb, type.__GetCustomModifiers());
					WriteType(module, bb, type.GetElementType());
					bb.WriteCompressedUInt(type.GetArrayRank());
					int[] sizes = type.__GetArraySizes();
					bb.WriteCompressedUInt(sizes.Length);
					for (int i = 0; i < sizes.Length; i++)
					{
						bb.WriteCompressedUInt(sizes[i]);
					}
					int[] lobounds = type.__GetArrayLowerBounds();
					bb.WriteCompressedUInt(lobounds.Length);
					for (int i = 0; i < lobounds.Length; i++)
					{
						bb.WriteCompressedInt(lobounds[i]);
					}
					return;
				}
				WriteCustomModifiers(module, bb, type.__GetCustomModifiers());
				type = type.GetElementType();
			}
			if (type.__IsBuiltIn)
			{
				bb.Write(type.SigElementType);
			}
			else if (type.IsGenericParameter)
			{
				bb.Write(type.SigElementType);
				bb.WriteCompressedUInt(type.GenericParameterPosition);
			}
			else if (!type.__IsMissing && type.IsGenericType)
			{
				WriteGenericSignature(module, bb, type);
			}
			else if (type.__IsFunctionPointer)
			{
				bb.Write(ELEMENT_TYPE_FNPTR);
				WriteStandAloneMethodSig(module, bb, type.__MethodSignature);
			}
			else
			{
				if (type.IsValueType)
				{
					bb.Write(ELEMENT_TYPE_VALUETYPE);
				}
				else
				{
					bb.Write(ELEMENT_TYPE_CLASS);
				}
				bb.WriteTypeDefOrRefEncoded(module.GetTypeToken(type).Token);
			}
		}
		private void WriteSigImpl(ModuleBuilder module, ByteBuffer bb, int parameterCount)
		{
			byte first;
			if ((callingConvention & CallingConventions.Any) == CallingConventions.VarArgs)
			{
				Debug.Assert(genericParamCount == 0);
				first = VARARG;
			}
			else if (genericParamCount > 0)
			{
				first = GENERIC;
			}
			else
			{
				first = DEFAULT;
			}
			if ((callingConvention & CallingConventions.HasThis) != 0)
			{
				first |= HASTHIS;
			}
			if ((callingConvention & CallingConventions.ExplicitThis) != 0)
			{
				first |= EXPLICITTHIS;
			}
			bb.Write(first);
			if (genericParamCount > 0)
			{
				bb.WriteCompressedUInt(genericParamCount);
			}
			bb.WriteCompressedUInt(parameterCount);
			// RetType
			WriteCustomModifiers(module, bb, modifiers.GetReturnTypeCustomModifiers());
			WriteType(module, bb, returnType);
			// Param
			for (int i = 0; i < parameterTypes.Length; i++)
			{
				WriteCustomModifiers(module, bb, modifiers.GetParameterCustomModifiers(i));
				WriteType(module, bb, parameterTypes[i]);
			}
		}
		internal override void WriteSig(ModuleBuilder module, ByteBuffer bb)
		{
			byte flags = PROPERTY;
			if ((callingConvention & CallingConventions.HasThis) != 0)
			{
				flags |= HASTHIS;
			}
			if ((callingConvention & CallingConventions.ExplicitThis) != 0)
			{
				flags |= EXPLICITTHIS;
			}
			if ((callingConvention & CallingConventions.VarArgs) != 0)
			{
				flags |= VARARG;
			}
			bb.Write(flags);
			bb.WriteCompressedUInt(parameterTypes == null ? 0 : parameterTypes.Length);
			WriteCustomModifiers(module, bb, customModifiers.GetReturnTypeCustomModifiers());
			WriteType(module, bb, propertyType);
			if (parameterTypes != null)
			{
				for (int i = 0; i < parameterTypes.Length; i++)
				{
					WriteCustomModifiers(module, bb, customModifiers.GetParameterCustomModifiers(i));
					WriteType(module, bb, parameterTypes[i]);
				}
			}
		}
Example #11
0
		internal static void WriteSignatureHelper(ModuleBuilder module, ByteBuffer bb, byte flags, ushort paramCount, List<Type> args)
		{
			bb.Write(flags);
			if (flags != FIELD)
			{
				bb.WriteCompressedUInt(paramCount);
			}
			foreach (Type type in args)
			{
				if (type == MarkerType.ModOpt)
				{
					bb.Write(ELEMENT_TYPE_CMOD_OPT);
				}
				else if (type == MarkerType.ModReq)
				{
					bb.Write(ELEMENT_TYPE_CMOD_REQD);
				}
				else if (type == MarkerType.Sentinel)
				{
					bb.Write(SENTINEL);
				}
				else if (type == MarkerType.Pinned)
				{
					bb.Write(ELEMENT_TYPE_PINNED);
				}
				else if (type == null)
				{
					bb.Write(ELEMENT_TYPE_VOID);
				}
				else
				{
					WriteType(module, bb, type);
				}
			}
		}
Example #12
0
		protected static void WriteType(ModuleBuilder module, ByteBuffer bb, Type type)
		{
			while (type.HasElementType)
			{
				if (type.__IsVector)
				{
					bb.Write(ELEMENT_TYPE_SZARRAY);
				}
				else if (type.IsArray)
				{
					int rank = type.GetArrayRank();
					bb.Write(ELEMENT_TYPE_ARRAY);
					// LAMESPEC the Type production (23.2.12) doesn't include CustomMod* for arrays, but the verifier allows it and ildasm also supports it
					WriteCustomModifiers(module, bb, type.__GetCustomModifiers());
					WriteType(module, bb, type.GetElementType());
					bb.WriteCompressedUInt(rank);
					int[] sizes = type.__GetArraySizes();
					bb.WriteCompressedUInt(sizes.Length);
					for (int i = 0; i < sizes.Length; i++)
					{
						bb.WriteCompressedUInt(sizes[i]);
					}
					int[] lobounds = type.__GetArrayLowerBounds();
					bb.WriteCompressedUInt(lobounds.Length);
					for (int i = 0; i < lobounds.Length; i++)
					{
						bb.WriteCompressedInt(lobounds[i]);
					}
					return;
				}
				else if (type.IsByRef)
				{
					bb.Write(ELEMENT_TYPE_BYREF);
				}
				else if (type.IsPointer)
				{
					bb.Write(ELEMENT_TYPE_PTR);
				}
				WriteCustomModifiers(module, bb, type.__GetCustomModifiers());
				type = type.GetElementType();
			}
			Universe u = module.universe;
			if (type == u.System_Void)
			{
				bb.Write(ELEMENT_TYPE_VOID);
			}
			else if (type == u.System_Int32)
			{
				bb.Write(ELEMENT_TYPE_I4);
			}
			else if (type == u.System_Boolean)
			{
				bb.Write(ELEMENT_TYPE_BOOLEAN);
			}
			else if (type == u.System_String)
			{
				bb.Write(ELEMENT_TYPE_STRING);
			}
			else if (type == u.System_Char)
			{
				bb.Write(ELEMENT_TYPE_CHAR);
			}
			else if (type == u.System_SByte)
			{
				bb.Write(ELEMENT_TYPE_I1);
			}
			else if (type == u.System_Byte)
			{
				bb.Write(ELEMENT_TYPE_U1);
			}
			else if (type == u.System_Int16)
			{
				bb.Write(ELEMENT_TYPE_I2);
			}
			else if (type == u.System_UInt16)
			{
				bb.Write(ELEMENT_TYPE_U2);
			}
			else if (type == u.System_UInt32)
			{
				bb.Write(ELEMENT_TYPE_U4);
			}
			else if (type == u.System_Int64)
			{
				bb.Write(ELEMENT_TYPE_I8);
			}
			else if (type == u.System_UInt64)
			{
				bb.Write(ELEMENT_TYPE_U8);
			}
			else if (type == u.System_Single)
			{
				bb.Write(ELEMENT_TYPE_R4);
			}
			else if (type == u.System_Double)
			{
				bb.Write(ELEMENT_TYPE_R8);
			}
			else if (type == u.System_IntPtr)
			{
				bb.Write(ELEMENT_TYPE_I);
			}
			else if (type == u.System_UIntPtr)
			{
				bb.Write(ELEMENT_TYPE_U);
			}
			else if (type == u.System_TypedReference)
			{
				bb.Write(ELEMENT_TYPE_TYPEDBYREF);
			}
			else if (type == u.System_Object)
			{
				bb.Write(ELEMENT_TYPE_OBJECT);
			}
			else if (type.IsGenericParameter)
			{
				if (type is UnboundGenericMethodParameter || type.DeclaringMethod != null)
				{
					bb.Write(ELEMENT_TYPE_MVAR);
				}
				else
				{
					bb.Write(ELEMENT_TYPE_VAR);
				}
				bb.WriteCompressedUInt(type.GenericParameterPosition);
			}
			else if (!type.__IsMissing && type.IsGenericType)
			{
				WriteGenericSignature(module, bb, type);
			}
			else if (type.__IsFunctionPointer)
			{
				bb.Write(ELEMENT_TYPE_FNPTR);
				WriteStandAloneMethodSig(module, bb, type.__MethodSignature);
			}
			else
			{
				if (type.IsValueType)
				{
					bb.Write(ELEMENT_TYPE_VALUETYPE);
				}
				else
				{
					bb.Write(ELEMENT_TYPE_CLASS);
				}
				bb.WriteTypeDefOrRefEncoded(module.GetTypeToken(type).Token);
			}
		}