// // This entry is targeted by the ILTransformer to implement Type.GetType()'s ability to detect the calling assembly and use it as // a default assembly name. // public static Type GetType(String typeName, String callingAssemblyName, bool throwOnError, bool ignoreCase) { LowLevelListWithIList<String> defaultAssemblies = new LowLevelListWithIList<String>(); defaultAssemblies.Add(callingAssemblyName); defaultAssemblies.AddRange(DefaultAssemblyNamesForGetType); return ReflectionCoreExecution.ExecutionDomain.GetType(typeName, throwOnError, ignoreCase, defaultAssemblies); }
// // This entry is targeted by the ILTransformer to implement Type.GetType()'s ability to detect the calling assembly and use it as // a default assembly name. // public static Type ExtensibleGetType(string typeName, string callingAssemblyName, Func<AssemblyName, Assembly> assemblyResolver, Func<Assembly, string, bool, Type> typeResolver, bool throwOnError, bool ignoreCase) { LowLevelListWithIList<String> defaultAssemblies = new LowLevelListWithIList<String>(); defaultAssemblies.Add(callingAssemblyName); defaultAssemblies.AddRange(DefaultAssemblyNamesForGetType); return ReflectionCoreExecution.ExecutionDomain.GetType(typeName, assemblyResolver, typeResolver, throwOnError, ignoreCase, defaultAssemblies); }
/// <summary> /// Convert each Oid's value to an ASCII string, then create an unmanaged array of "numOids" LPSTR pointers, one for each Oid. /// "numOids" is the number of LPSTR pointers. This is normally the same as oids.Count, except in the case where a malicious caller /// appends to the OidCollection while this method is in progress. In such a case, this method guarantees only that this won't create /// an unmanaged buffer overflow condition. /// </summary> public static SafeHandle ToLpstrArray(this OidCollection oids, out int numOids) { if (oids == null || oids.Count == 0) { numOids = 0; return SafeLocalAllocHandle.InvalidHandle; } // Copy the oid strings to a local list to prevent a security race condition where // the OidCollection or individual oids can be modified by another thread and // potentially cause a buffer overflow LowLevelListWithIList<byte[]> oidStrings = new LowLevelListWithIList<byte[]>(); foreach (Oid oid in oids) { byte[] oidString = oid.ValueAsAscii(); oidStrings.Add(oidString); } numOids = oidStrings.Count; unsafe { int allocationSize = checked(numOids * sizeof(void*)); foreach (byte[] oidString in oidStrings) { checked { allocationSize += oidString.Length + 1; } } SafeLocalAllocHandle safeLocalAllocHandle = SafeLocalAllocHandle.Create(allocationSize); byte** pOidPointers = (byte**)(safeLocalAllocHandle.DangerousGetHandle()); byte* pOidContents = (byte*)(pOidPointers + numOids); for (int i = 0; i < numOids; i++) { pOidPointers[i] = pOidContents; byte[] oidString = oidStrings[i]; Marshal.Copy(oidString, 0, new IntPtr(pOidContents), oidString.Length); pOidContents[oidString.Length] = 0; pOidContents += oidString.Length + 1; } return safeLocalAllocHandle; } }
// // Foo or Foo+Inner or Foo[String] or Foo+Inner[String] // private NonQualifiedTypeName ParseNamedOrConstructedGenericTypeName() { NamedTypeName namedType = ParseNamedTypeName(); // Because "[" is used both for generic arguments and array indexes, we must peek two characters deep. if (!(_lexer.Peek == TokenType.OpenSqBracket && (_lexer.PeekSecond == TokenType.Other || _lexer.PeekSecond == TokenType.OpenSqBracket))) return namedType; else { _lexer.Skip(); LowLevelListWithIList<TypeName> genericTypeArguments = new LowLevelListWithIList<TypeName>(); for (;;) { TypeName genericTypeArgument = ParseGenericTypeArgument(); genericTypeArguments.Add(genericTypeArgument); TokenType token = _lexer.GetNextToken(); if (token == TokenType.CloseSqBracket) break; if (token != TokenType.Comma) throw new ArgumentException(); } return new ConstructedGenericTypeName(namedType, genericTypeArguments); } }
// // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException. // internal sealed override IList<CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata) { int index = 0; LowLevelList<Handle> lazyCtorTypeHandles = null; LowLevelListWithIList<CustomAttributeTypedArgument> customAttributeTypedArguments = new LowLevelListWithIList<CustomAttributeTypedArgument>(); foreach (FixedArgumentHandle fixedArgumentHandle in _customAttribute.FixedArguments) { CustomAttributeTypedArgument customAttributeTypedArgument = ParseFixedArgument( _reader, fixedArgumentHandle, throwIfMissingMetadata, delegate () { // If we got here, the custom attribute blob lacked type information (this is actually the typical case.) We must fallback to // parsing the constructor's signature to get the type info. if (lazyCtorTypeHandles == null) { IEnumerable<ParameterTypeSignatureHandle> parameterTypeSignatureHandles; HandleType handleType = _customAttribute.Constructor.HandleType; switch (handleType) { case HandleType.QualifiedMethod: parameterTypeSignatureHandles = _customAttribute.Constructor.ToQualifiedMethodHandle(_reader).GetQualifiedMethod(_reader).Method.GetMethod(_reader).Signature.GetMethodSignature(_reader).Parameters; break; case HandleType.MemberReference: parameterTypeSignatureHandles = _customAttribute.Constructor.ToMemberReferenceHandle(_reader).GetMemberReference(_reader).Signature.ToMethodSignatureHandle(_reader).GetMethodSignature(_reader).Parameters; break; default: throw new BadImageFormatException(); } LowLevelList<Handle> ctorTypeHandles = new LowLevelList<Handle>(); foreach (ParameterTypeSignatureHandle parameterTypeSignatureHandle in parameterTypeSignatureHandles) { ctorTypeHandles.Add(parameterTypeSignatureHandle.GetParameterTypeSignature(_reader).Type); } lazyCtorTypeHandles = ctorTypeHandles; } Handle typeHandle = lazyCtorTypeHandles[index]; Exception exception = null; RuntimeType argumentType = _reflectionDomain.TryResolve(_reader, typeHandle, new TypeContext(null, null), ref exception); if (argumentType == null) { if (throwIfMissingMetadata) throw exception; return null; } return argumentType; } ); if (customAttributeTypedArgument.ArgumentType == null) { Debug.Assert(!throwIfMissingMetadata); return null; } customAttributeTypedArguments.Add(customAttributeTypedArgument); index++; } return customAttributeTypedArguments; }
// // Wrap a custom attribute argument (or an element of an array-typed custom attribute argument) in a CustomAttributeTypeArgument structure // for insertion into a CustomAttributeData value. // private CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(Object value, Type argumentType) { // To support reflection domains other than the execution domain, we'll have to translate argumentType to one of the values off // _reflectionDomain.FoundationTypes rather than using the direct value of value.GetType(). It's unclear how to do this for // enum types. Cross that bridge if ever get to it. Debug.Assert(_reflectionDomain is ExecutionDomain); if (argumentType.Equals(typeof(Object))) { // If the declared attribute type is System.Object, we must report the type based on the runtime value. if (value == null) argumentType = typeof(String); // Why is null reported as System.String? Because that's what the desktop CLR does. else if (value is Type) argumentType = typeof(Type); // value.GetType() will not actually be System.Type - rather it will be some internal implementation type. We only want to report it as System.Type. else argumentType = value.GetType(); } Array arrayValue = value as Array; if (arrayValue != null) { if (!argumentType.IsArray) throw new BadImageFormatException(); Type reportedElementType = argumentType.GetElementType(); LowLevelListWithIList<CustomAttributeTypedArgument> elementTypedArguments = new LowLevelListWithIList<CustomAttributeTypedArgument>(); foreach (Object elementValue in arrayValue) { CustomAttributeTypedArgument elementTypedArgument = WrapInCustomAttributeTypedArgument(elementValue, reportedElementType); elementTypedArguments.Add(elementTypedArgument); } return ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, new ReadOnlyCollection<CustomAttributeTypedArgument>(elementTypedArguments)); } else { return ExtensibleCustomAttributeData.CreateCustomAttributeTypedArgument(argumentType, value); } }
// // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException. // internal sealed override IList<CustomAttributeNamedArgument> GetNamedArguments(bool throwIfMissingMetadata) { LowLevelListWithIList<CustomAttributeNamedArgument> customAttributeNamedArguments = new LowLevelListWithIList<CustomAttributeNamedArgument>(); foreach (NamedArgumentHandle namedArgumentHandle in _customAttribute.NamedArguments) { NamedArgument namedArgument = namedArgumentHandle.GetNamedArgument(_reader); String memberName = namedArgument.Name.GetString(_reader); bool isField = (namedArgument.Flags == NamedArgumentMemberKind.Field); CustomAttributeTypedArgument typedValue = ParseFixedArgument( _reader, namedArgument.Value, throwIfMissingMetadata, delegate () { // We got here because the custom attribute blob did not inclue type information. For named arguments, this is considered illegal metadata // (ECMA always includes type info for named arguments.) throw new BadImageFormatException(); } ); if (typedValue.ArgumentType == null) { Debug.Assert(!throwIfMissingMetadata); return null; } customAttributeNamedArguments.Add(ExtensibleCustomAttributeData.CreateCustomAttributeNamedArgument(this.AttributeType, memberName, isField, typedValue)); } return customAttributeNamedArguments; }
// // Wrap a custom attribute argument (or an element of an array-typed custom attribute argument) in a CustomAttributeTypeArgument structure // for insertion into a CustomAttributeData value. // private CustomAttributeTypedArgument WrapInCustomAttributeTypedArgument(Object value, Type argumentType) { if (argumentType.Equals(typeof(Object))) { // If the declared attribute type is System.Object, we must report the type based on the runtime value. if (value == null) argumentType = typeof(String); // Why is null reported as System.String? Because that's what the desktop CLR does. else if (value is Type) argumentType = typeof(Type); // value.GetType() will not actually be System.Type - rather it will be some internal implementation type. We only want to report it as System.Type. else argumentType = value.GetType(); } // Handle the array case IEnumerable enumerableValue = value as IEnumerable; if (enumerableValue != null && !(value is String)) { if (!argumentType.IsArray) throw new BadImageFormatException(); Type reportedElementType = argumentType.GetElementType(); LowLevelListWithIList<CustomAttributeTypedArgument> elementTypedArguments = new LowLevelListWithIList<CustomAttributeTypedArgument>(); foreach (Object elementValue in enumerableValue) { CustomAttributeTypedArgument elementTypedArgument = WrapInCustomAttributeTypedArgument(elementValue, reportedElementType); elementTypedArguments.Add(elementTypedArgument); } return new CustomAttributeTypedArgument(argumentType, new ReadOnlyCollection<CustomAttributeTypedArgument>(elementTypedArguments)); } else { return new CustomAttributeTypedArgument(argumentType, value); } }
/// <summary> /// Flattens an <see cref="AggregateException"/> instances into a single, new instance. /// </summary> /// <returns>A new, flattened <see cref="AggregateException"/>.</returns> /// <remarks> /// If any inner exceptions are themselves instances of /// <see cref="AggregateException"/>, this method will recursively flatten all of them. The /// inner exceptions returned in the new <see cref="AggregateException"/> /// will be the union of all of the the inner exceptions from exception tree rooted at the provided /// <see cref="AggregateException"/> instance. /// </remarks> public AggregateException Flatten() { // Initialize a collection to contain the flattened exceptions. LowLevelListWithIList<Exception> flattenedExceptions = new LowLevelListWithIList<Exception>(); // Create a list to remember all aggregates to be flattened, this will be accessed like a FIFO queue LowLevelList<AggregateException> exceptionsToFlatten = new LowLevelList<AggregateException>(); exceptionsToFlatten.Add(this); int nDequeueIndex = 0; // Continue removing and recursively flattening exceptions, until there are no more. while (exceptionsToFlatten.Count > nDequeueIndex) { // dequeue one from exceptionsToFlatten IList<Exception> currentInnerExceptions = exceptionsToFlatten[nDequeueIndex++].InnerExceptions; for (int i = 0; i < currentInnerExceptions.Count; i++) { Exception currentInnerException = currentInnerExceptions[i]; if (currentInnerException == null) { continue; } AggregateException currentInnerAsAggregate = currentInnerException as AggregateException; // If this exception is an aggregate, keep it around for later. Otherwise, // simply add it to the list of flattened exceptions to be returned. if (currentInnerAsAggregate != null) { exceptionsToFlatten.Add(currentInnerAsAggregate); } else { flattenedExceptions.Add(currentInnerException); } } } return new AggregateException(Message, flattenedExceptions); }
public override Object InvokeMember( String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) { const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF; const BindingFlags InvocationMask = (BindingFlags)0x0000FF00; const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty; const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField; const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300; const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty; if (IsGenericParameter) throw new InvalidOperationException(SR.Arg_GenericParameter); #region Preconditions if ((bindingFlags & InvocationMask) == 0) // "Must specify binding flags describing the invoke operation required." throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags)); // Provide a default binding mask if none is provided if ((bindingFlags & MemberBindingMask) == 0) { bindingFlags |= BindingFlags.Instance | BindingFlags.Public; if ((bindingFlags & BindingFlags.CreateInstance) == 0) bindingFlags |= BindingFlags.Static; } // There must not be more named parameters than provided arguments if (namedParams != null) { if (providedArgs != null) { if (namedParams.Length > providedArgs.Length) // "Named parameter array can not be bigger than argument array." throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams)); } else { if (namedParams.Length != 0) // "Named parameter array can not be bigger than argument array." throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams)); } } #endregion #region COM Interop if (target != null && target.GetType().IsCOMObject) throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupportedInvokeMemberCom); #endregion #region Check that any named paramters are not null if (namedParams != null && Array.IndexOf(namedParams, null) != -1) // "Named parameter value must not be null." throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams)); #endregion int argCnt = (providedArgs != null) ? providedArgs.Length : 0; #region Get a Binder if (binder == null) binder = DefaultBinder; bool bDefaultBinder = (binder == DefaultBinder); #endregion #region Delegate to Activator.CreateInstance if ((bindingFlags & BindingFlags.CreateInstance) != 0) { if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0) // "Can not specify both CreateInstance and another access type." throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags)); return Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture); } #endregion // PutDispProperty and\or PutRefDispProperty ==> SetProperty. if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0) bindingFlags |= BindingFlags.SetProperty; #region Name if (name == null) throw new ArgumentNullException(nameof(name)); if (name.Length == 0 || name.Equals(@"[DISPID=0]")) { name = GetDefaultMemberName(); if (name == null) { // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString name = "ToString"; } } #endregion #region GetField or SetField bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0; bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0; if (IsGetField || IsSetField) { #region Preconditions if (IsGetField) { if (IsSetField) // "Can not specify both Get and Set on a field." throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags)); if ((bindingFlags & BindingFlags.SetProperty) != 0) // "Can not specify both GetField and SetProperty." throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags)); } else { Debug.Assert(IsSetField); if (providedArgs == null) throw new ArgumentNullException(nameof(providedArgs)); if ((bindingFlags & BindingFlags.GetProperty) != 0) // "Can not specify both SetField and GetProperty." throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags)); if ((bindingFlags & BindingFlags.InvokeMethod) != 0) // "Can not specify Set on a Field and Invoke on a method." throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags)); } #endregion #region Lookup Field FieldInfo selFld = null; FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[]; Debug.Assert(flds != null); if (flds.Length == 1) { selFld = flds[0]; } else if (flds.Length > 0) { selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture); } #endregion if (selFld != null) { #region Invocation on a field if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, CommonRuntimeTypes.Array)) { #region Invocation of an array Field int idxCnt; if ((bindingFlags & BindingFlags.GetField) != 0) { idxCnt = argCnt; } else { idxCnt = argCnt - 1; } if (idxCnt > 0) { // Verify that all of the index values are ints int[] idx = new int[idxCnt]; for (int i = 0; i < idxCnt; i++) { try { idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null); } catch (InvalidCastException) { throw new ArgumentException(SR.Arg_IndexMustBeInt); } } // Set or get the value... Array a = (Array)selFld.GetValue(target); // Set or get the value in the array if ((bindingFlags & BindingFlags.GetField) != 0) { return a.GetValue(idx); } else { a.SetValue(providedArgs[idxCnt], idx); return null; } } #endregion } if (IsGetField) { #region Get the field value if (argCnt != 0) throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags)); return selFld.GetValue(target); #endregion } else { #region Set the field Value if (argCnt != 1) throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags)); selFld.SetValue(target, providedArgs[0], bindingFlags, binder, culture); return null; #endregion } #endregion } if ((bindingFlags & BinderNonFieldGetSet) == 0) throw new MissingFieldException(FullName, name); } #endregion #region Property PreConditions // @Legacy - This is RTM behavior bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0; bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0; if (isGetProperty || isSetProperty) { #region Preconditions if (isGetProperty) { Debug.Assert(!IsSetField); if (isSetProperty) throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags)); } else { Debug.Assert(isSetProperty); Debug.Assert(!IsGetField); if ((bindingFlags & BindingFlags.InvokeMethod) != 0) throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags)); } #endregion } #endregion MethodInfo[] finalists = null; MethodInfo finalist = null; #region BindingFlags.InvokeMethod if ((bindingFlags & BindingFlags.InvokeMethod) != 0) { #region Lookup Methods MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[]; LowLevelListWithIList<MethodInfo> results = null; for (int i = 0; i < semiFinalists.Length; i++) { MethodInfo semiFinalist = semiFinalists[i]; Debug.Assert(semiFinalist != null); if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt])) continue; if (finalist == null) { finalist = semiFinalist; } else { if (results == null) { results = new LowLevelListWithIList<MethodInfo>(semiFinalists.Length); results.Add(finalist); } results.Add(semiFinalist); } } if (results != null) { Debug.Assert(results.Count > 1); finalists = new MethodInfo[results.Count]; results.CopyTo(finalists, 0); } #endregion } #endregion Debug.Assert(finalists == null || finalist != null); #region BindingFlags.GetProperty or BindingFlags.SetProperty if (finalist == null && isGetProperty || isSetProperty) { #region Lookup Property PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[]; LowLevelListWithIList<MethodInfo> results = null; for (int i = 0; i < semiFinalists.Length; i++) { MethodInfo semiFinalist = null; if (isSetProperty) { semiFinalist = semiFinalists[i].GetSetMethod(true); } else { semiFinalist = semiFinalists[i].GetGetMethod(true); } if (semiFinalist == null) continue; BindingFlags expectedBindingFlags = semiFinalist.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; if ((bindingFlags & expectedBindingFlags) != expectedBindingFlags) continue; if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt])) continue; if (finalist == null) { finalist = semiFinalist; } else { if (results == null) { results = new LowLevelListWithIList<MethodInfo>(semiFinalists.Length); results.Add(finalist); } results.Add(semiFinalist); } } if (results != null) { Debug.Assert(results.Count > 1); finalists = new MethodInfo[results.Count]; results.CopyTo(finalists, 0); } #endregion } #endregion if (finalist != null) { #region Invoke if (finalists == null && argCnt == 0 && finalist.GetParametersNoCopy().Length == 0 && (bindingFlags & BindingFlags.OptionalParamBinding) == 0) { //if (useCache && argCnt == props[0].GetParameters().Length) // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]); return finalist.Invoke(target, bindingFlags, binder, providedArgs, culture); } if (finalists == null) finalists = new MethodInfo[] { finalist }; if (providedArgs == null) providedArgs = Array.Empty<object>(); Object state = null; MethodBase invokeMethod = null; try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); } catch (MissingMethodException) { } if (invokeMethod == null) throw new MissingMethodException(FullName, name); //if (useCache && argCnt == invokeMethod.GetParameters().Length) // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod); Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture); if (state != null) binder.ReorderArgumentArray(ref providedArgs, state); return result; #endregion } throw new MissingMethodException(FullName, name); }
/// <summary> /// This callback gets called whenever a module gets registered. It adds the metadata reader /// for the new module to the available scopes. The lock in ExecutionEnvironmentImplementation ensures /// that this function may never be called concurrently so that we can assume that two threads /// never update the reader and scope list at the same time. /// </summary> /// <param name="moduleHandle">Module handle to register</param> private void RegisterModule(IntPtr moduleHandle) { MetadataReader newReader = _executionEnvironment.GetMetadataReaderForModule(moduleHandle); if (newReader == null) { return; } // Build new reader list LowLevelListWithIList<MetadataReader> readers = new LowLevelListWithIList<MetadataReader>(_readers.Count + 1); foreach (MetadataReader oldReader in _readers) { readers.Add(oldReader); } readers.Add(newReader); LowLevelDictionaryWithIEnumerable<string, ScopeDefinitionGroup> scopeGroups = new LowLevelDictionaryWithIEnumerable<string, ScopeDefinitionGroup>(); foreach (KeyValuePair<string, ScopeDefinitionGroup> oldGroup in _scopeGroups) { scopeGroups.Add(oldGroup.Key, oldGroup.Value); } AddScopesFromReaderToGroups(scopeGroups, newReader); // Update reader and scope list _readers = readers; _scopeGroups = scopeGroups; }
public override Object InvokeMember( String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) { const BindingFlags MemberBindingMask = (BindingFlags)0x000000FF; const BindingFlags InvocationMask = (BindingFlags)0x0000FF00; const BindingFlags BinderGetSetProperty = BindingFlags.GetProperty | BindingFlags.SetProperty; const BindingFlags BinderGetSetField = BindingFlags.GetField | BindingFlags.SetField; const BindingFlags BinderNonFieldGetSet = (BindingFlags)0x00FFF300; const BindingFlags BinderNonCreateInstance = BindingFlags.InvokeMethod | BinderGetSetField | BinderGetSetProperty; if (IsGenericParameter) { throw new InvalidOperationException(SR.Arg_GenericParameter); } #region Preconditions if ((bindingFlags & InvocationMask) == 0) { // "Must specify binding flags describing the invoke operation required." throw new ArgumentException(SR.Arg_NoAccessSpec, nameof(bindingFlags)); } // Provide a default binding mask if none is provided if ((bindingFlags & MemberBindingMask) == 0) { bindingFlags |= BindingFlags.Instance | BindingFlags.Public; if ((bindingFlags & BindingFlags.CreateInstance) == 0) { bindingFlags |= BindingFlags.Static; } } // There must not be more named parameters than provided arguments if (namedParams != null) { if (providedArgs != null) { if (namedParams.Length > providedArgs.Length) { // "Named parameter array can not be bigger than argument array." throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams)); } } else { if (namedParams.Length != 0) { // "Named parameter array can not be bigger than argument array." throw new ArgumentException(SR.Arg_NamedParamTooBig, nameof(namedParams)); } } } #endregion #region COM Interop if (target != null && target.GetType().IsCOMObject) { throw new PlatformNotSupportedException(SR.Arg_PlatformNotSupportedInvokeMemberCom); } #endregion #region Check that any named paramters are not null if (namedParams != null && Array.IndexOf(namedParams, null) != -1) { // "Named parameter value must not be null." throw new ArgumentException(SR.Arg_NamedParamNull, nameof(namedParams)); } #endregion int argCnt = (providedArgs != null) ? providedArgs.Length : 0; #region Get a Binder if (binder == null) { binder = DefaultBinder; } bool bDefaultBinder = (binder == DefaultBinder); #endregion #region Delegate to Activator.CreateInstance if ((bindingFlags & BindingFlags.CreateInstance) != 0) { if ((bindingFlags & BindingFlags.CreateInstance) != 0 && (bindingFlags & BinderNonCreateInstance) != 0) { // "Can not specify both CreateInstance and another access type." throw new ArgumentException(SR.Arg_CreatInstAccess, nameof(bindingFlags)); } return(Activator.CreateInstance(this, bindingFlags, binder, providedArgs, culture)); } #endregion // PutDispProperty and\or PutRefDispProperty ==> SetProperty. if ((bindingFlags & (BindingFlags.PutDispProperty | BindingFlags.PutRefDispProperty)) != 0) { bindingFlags |= BindingFlags.SetProperty; } #region Name if (name == null) { throw new ArgumentNullException(nameof(name)); } if (name.Length == 0 || name.Equals(@"[DISPID=0]")) { name = GetDefaultMemberName(); if (name == null) { // in InvokeMember we always pretend there is a default member if none is provided and we make it ToString name = "ToString"; } } #endregion #region GetField or SetField bool IsGetField = (bindingFlags & BindingFlags.GetField) != 0; bool IsSetField = (bindingFlags & BindingFlags.SetField) != 0; if (IsGetField || IsSetField) { #region Preconditions if (IsGetField) { if (IsSetField) { // "Can not specify both Get and Set on a field." throw new ArgumentException(SR.Arg_FldSetGet, nameof(bindingFlags)); } if ((bindingFlags & BindingFlags.SetProperty) != 0) { // "Can not specify both GetField and SetProperty." throw new ArgumentException(SR.Arg_FldGetPropSet, nameof(bindingFlags)); } } else { Debug.Assert(IsSetField); if (providedArgs == null) { throw new ArgumentNullException(nameof(providedArgs)); } if ((bindingFlags & BindingFlags.GetProperty) != 0) { // "Can not specify both SetField and GetProperty." throw new ArgumentException(SR.Arg_FldSetPropGet, nameof(bindingFlags)); } if ((bindingFlags & BindingFlags.InvokeMethod) != 0) { // "Can not specify Set on a Field and Invoke on a method." throw new ArgumentException(SR.Arg_FldSetInvoke, nameof(bindingFlags)); } } #endregion #region Lookup Field FieldInfo selFld = null; FieldInfo[] flds = GetMember(name, MemberTypes.Field, bindingFlags) as FieldInfo[]; Debug.Assert(flds != null); if (flds.Length == 1) { selFld = flds[0]; } else if (flds.Length > 0) { selFld = binder.BindToField(bindingFlags, flds, IsGetField ? Empty.Value : providedArgs[0], culture); } #endregion if (selFld != null) { #region Invocation on a field if (selFld.FieldType.IsArray || Object.ReferenceEquals(selFld.FieldType, typeof(System.Array))) { #region Invocation of an array Field int idxCnt; if ((bindingFlags & BindingFlags.GetField) != 0) { idxCnt = argCnt; } else { idxCnt = argCnt - 1; } if (idxCnt > 0) { // Verify that all of the index values are ints int[] idx = new int[idxCnt]; for (int i = 0; i < idxCnt; i++) { try { idx[i] = ((IConvertible)providedArgs[i]).ToInt32(null); } catch (InvalidCastException) { throw new ArgumentException(SR.Arg_IndexMustBeInt); } } // Set or get the value... Array a = (Array)selFld.GetValue(target); // Set or get the value in the array if ((bindingFlags & BindingFlags.GetField) != 0) { return(a.GetValue(idx)); } else { a.SetValue(providedArgs[idxCnt], idx); return(null); } } #endregion } if (IsGetField) { #region Get the field value if (argCnt != 0) { throw new ArgumentException(SR.Arg_FldGetArgErr, nameof(bindingFlags)); } return(selFld.GetValue(target)); #endregion } else { #region Set the field Value if (argCnt != 1) { throw new ArgumentException(SR.Arg_FldSetArgErr, nameof(bindingFlags)); } selFld.SetValue(target, providedArgs[0], bindingFlags, binder, culture); return(null); #endregion } #endregion } if ((bindingFlags & BinderNonFieldGetSet) == 0) { throw new MissingFieldException(FullName, name); } } #endregion #region Property PreConditions // @Legacy - This is RTM behavior bool isGetProperty = (bindingFlags & BindingFlags.GetProperty) != 0; bool isSetProperty = (bindingFlags & BindingFlags.SetProperty) != 0; if (isGetProperty || isSetProperty) { #region Preconditions if (isGetProperty) { Debug.Assert(!IsSetField); if (isSetProperty) { throw new ArgumentException(SR.Arg_PropSetGet, nameof(bindingFlags)); } } else { Debug.Assert(isSetProperty); Debug.Assert(!IsGetField); if ((bindingFlags & BindingFlags.InvokeMethod) != 0) { throw new ArgumentException(SR.Arg_PropSetInvoke, nameof(bindingFlags)); } } #endregion } #endregion MethodInfo[] finalists = null; MethodInfo finalist = null; #region BindingFlags.InvokeMethod if ((bindingFlags & BindingFlags.InvokeMethod) != 0) { #region Lookup Methods MethodInfo[] semiFinalists = GetMember(name, MemberTypes.Method, bindingFlags) as MethodInfo[]; LowLevelListWithIList <MethodInfo> results = null; for (int i = 0; i < semiFinalists.Length; i++) { MethodInfo semiFinalist = semiFinalists[i]; Debug.Assert(semiFinalist != null); if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt])) { continue; } if (finalist == null) { finalist = semiFinalist; } else { if (results == null) { results = new LowLevelListWithIList <MethodInfo>(semiFinalists.Length); results.Add(finalist); } results.Add(semiFinalist); } } if (results != null) { Debug.Assert(results.Count > 1); finalists = new MethodInfo[results.Count]; results.CopyTo(finalists, 0); } #endregion } #endregion Debug.Assert(finalists == null || finalist != null); #region BindingFlags.GetProperty or BindingFlags.SetProperty if (finalist == null && isGetProperty || isSetProperty) { #region Lookup Property PropertyInfo[] semiFinalists = GetMember(name, MemberTypes.Property, bindingFlags) as PropertyInfo[]; LowLevelListWithIList <MethodInfo> results = null; for (int i = 0; i < semiFinalists.Length; i++) { MethodInfo semiFinalist = null; if (isSetProperty) { semiFinalist = semiFinalists[i].GetSetMethod(true); } else { semiFinalist = semiFinalists[i].GetGetMethod(true); } if (semiFinalist == null) { continue; } BindingFlags expectedBindingFlags = semiFinalist.IsPublic ? BindingFlags.Public : BindingFlags.NonPublic; if ((bindingFlags & expectedBindingFlags) != expectedBindingFlags) { continue; } if (!semiFinalist.QualifiesBasedOnParameterCount(bindingFlags, CallingConventions.Any, new Type[argCnt])) { continue; } if (finalist == null) { finalist = semiFinalist; } else { if (results == null) { results = new LowLevelListWithIList <MethodInfo>(semiFinalists.Length); results.Add(finalist); } results.Add(semiFinalist); } } if (results != null) { Debug.Assert(results.Count > 1); finalists = new MethodInfo[results.Count]; results.CopyTo(finalists, 0); } #endregion } #endregion if (finalist != null) { #region Invoke if (finalists == null && argCnt == 0 && finalist.GetParametersNoCopy().Length == 0 && (bindingFlags & BindingFlags.OptionalParamBinding) == 0) { //if (useCache && argCnt == props[0].GetParameters().Length) // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, props[0]); return(finalist.Invoke(target, bindingFlags, binder, providedArgs, culture)); } if (finalists == null) { finalists = new MethodInfo[] { finalist } } ; if (providedArgs == null) { providedArgs = Array.Empty <object>(); } Object state = null; MethodBase invokeMethod = null; try { invokeMethod = binder.BindToMethod(bindingFlags, finalists, ref providedArgs, modifiers, culture, namedParams, out state); } catch (MissingMethodException) { } if (invokeMethod == null) { throw new MissingMethodException(FullName, name); } //if (useCache && argCnt == invokeMethod.GetParameters().Length) // AddMethodToCache(name, bindingFlags, argCnt, providedArgs, invokeMethod); Object result = ((MethodInfo)invokeMethod).Invoke(target, bindingFlags, binder, providedArgs, culture); if (state != null) { binder.ReorderArgumentArray(ref providedArgs, state); } return(result); #endregion } throw new MissingMethodException(FullName, name); } }
// // If throwIfMissingMetadata is false, returns null rather than throwing a MissingMetadataException. // internal sealed override IList <CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata) { int index = 0; LowLevelList <Handle> lazyCtorTypeHandles = null; LowLevelListWithIList <CustomAttributeTypedArgument> customAttributeTypedArguments = new LowLevelListWithIList <CustomAttributeTypedArgument>(); foreach (FixedArgumentHandle fixedArgumentHandle in _customAttribute.FixedArguments) { CustomAttributeTypedArgument customAttributeTypedArgument = ParseFixedArgument( _reader, fixedArgumentHandle, throwIfMissingMetadata, delegate() { // If we got here, the custom attribute blob lacked type information (this is actually the typical case.) We must fallback to // parsing the constructor's signature to get the type info. if (lazyCtorTypeHandles == null) { IEnumerable <ParameterTypeSignatureHandle> parameterTypeSignatureHandles; HandleType handleType = _customAttribute.Constructor.HandleType; switch (handleType) { case HandleType.QualifiedMethod: parameterTypeSignatureHandles = _customAttribute.Constructor.ToQualifiedMethodHandle(_reader).GetQualifiedMethod(_reader).Method.GetMethod(_reader).Signature.GetMethodSignature(_reader).Parameters; break; case HandleType.MemberReference: parameterTypeSignatureHandles = _customAttribute.Constructor.ToMemberReferenceHandle(_reader).GetMemberReference(_reader).Signature.ToMethodSignatureHandle(_reader).GetMethodSignature(_reader).Parameters; break; default: throw new BadImageFormatException(); } LowLevelList <Handle> ctorTypeHandles = new LowLevelList <Handle>(); foreach (ParameterTypeSignatureHandle parameterTypeSignatureHandle in parameterTypeSignatureHandles) { ctorTypeHandles.Add(parameterTypeSignatureHandle.GetParameterTypeSignature(_reader).Type); } lazyCtorTypeHandles = ctorTypeHandles; } Handle typeHandle = lazyCtorTypeHandles[index]; Exception exception = null; RuntimeType argumentType = _reflectionDomain.TryResolve(_reader, typeHandle, new TypeContext(null, null), ref exception); if (argumentType == null) { if (throwIfMissingMetadata) { throw exception; } return(null); } return(argumentType); } ); if (customAttributeTypedArgument.ArgumentType == null) { Debug.Assert(!throwIfMissingMetadata); return(null); } customAttributeTypedArguments.Add(customAttributeTypedArgument); index++; } return(customAttributeTypedArguments); }
// // If throwIfMissingMetadata is false, returns null rather than throwing a missing metadata exception. // internal sealed override IList <CustomAttributeTypedArgument> GetConstructorArguments(bool throwIfMissingMetadata) { int index = 0; HandleCollection parameterTypeSignatureHandles; HandleType handleType = _customAttribute.Constructor.HandleType; switch (handleType) { case HandleType.QualifiedMethod: parameterTypeSignatureHandles = _customAttribute.Constructor.ToQualifiedMethodHandle(_reader).GetQualifiedMethod(_reader).Method.GetMethod(_reader).Signature.GetMethodSignature(_reader).Parameters; break; case HandleType.MemberReference: parameterTypeSignatureHandles = _customAttribute.Constructor.ToMemberReferenceHandle(_reader).GetMemberReference(_reader).Signature.ToMethodSignatureHandle(_reader).GetMethodSignature(_reader).Parameters; break; default: throw new BadImageFormatException(); } Handle[] ctorTypeHandles = parameterTypeSignatureHandles.ToArray(); LowLevelListWithIList <CustomAttributeTypedArgument> customAttributeTypedArguments = new LowLevelListWithIList <CustomAttributeTypedArgument>(); foreach (Handle fixedArgumentHandle in _customAttribute.FixedArguments) { Handle typeHandle = ctorTypeHandles[index]; Exception? exception = null; RuntimeTypeInfo?argumentType = typeHandle.TryResolve(_reader, new TypeContext(null, null), ref exception); if (argumentType == null) { if (throwIfMissingMetadata) { throw exception !; } return(null); } Exception e = fixedArgumentHandle.TryParseConstantValue(_reader, out object?value); CustomAttributeTypedArgument customAttributeTypedArgument; if (e != null) { if (throwIfMissingMetadata) { throw e; } else { return(null); } } else { customAttributeTypedArgument = WrapInCustomAttributeTypedArgument(value, argumentType); } customAttributeTypedArguments.Add(customAttributeTypedArgument); index++; } return(customAttributeTypedArguments); }