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]); } } }
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); } } }
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); } }