internal static void SetReferences( object[] arguments, MethodInformation methodInformation, object[] originalArguments) { using (PSObject.memberResolution.TraceScope("Checking for possible references.")) { ParameterInformation[] parameters = methodInformation.parameters; for (int index = 0; index < originalArguments.Length && index < parameters.Length && index < arguments.Length; ++index) { switch (originalArguments[index]) { case PSReference baseObject: label_4: if (parameters[index].isByRef) { object obj = arguments[index]; PSObject.memberResolution.WriteLine("Argument '{0}' was a reference so it will be set to \"{1}\".", (object)(index + 1), obj); baseObject.Value = obj; break; } break; case PSObject psObject: if (!(psObject.BaseObject is PSReference baseObject)) { break; } goto label_4; } } } }
private object AuxillaryInvokeMethod( ManagementObject obj, BaseWMIAdapter.WMIMethodCacheEntry mdata, object[] arguments) { MethodInformation[] methods = new MethodInformation[1] { mdata.MethodInfoStructure }; object[] newArguments; Adapter.GetBestMethodAndArguments(mdata.Name, methods, arguments, out newArguments); ParameterInformation[] parameters = mdata.MethodInfoStructure.parameters; Adapter.tracer.WriteLine("Parameters found {0}. Arguments supplied {0}", (object)parameters.Length, (object)newArguments.Length); ManagementBaseObject methodParameters = BaseWMIAdapter.CreateClassFrmObject((ManagementBaseObject)obj).GetMethodParameters(mdata.Name); for (int index = 0; index < parameters.Length; ++index) { BaseWMIAdapter.WMIParameterInformation parameterInformation = (BaseWMIAdapter.WMIParameterInformation)parameters[index]; if (index < arguments.Length && arguments[index] == null) { newArguments[index] = (object)null; } methodParameters[parameterInformation.Name] = newArguments[index]; } return(this.InvokeManagementMethod(obj, mdata.Name, methodParameters)); }
internal object GetValue(object target, object[] arguments) { System.Type type = target.GetType(); try { object[] objArray; Collection <int> methods = new Collection <int> { this.getterIndex }; MethodInformation[] informationArray = ComUtil.GetMethodInformationArray(this.typeInfo, methods, false); MethodInformation methodInformation = Adapter.GetBestMethodAndArguments(this.Name, informationArray, arguments, out objArray); object obj2 = type.InvokeMember(this.name, BindingFlags.GetProperty | BindingFlags.IgnoreCase, null, target, objArray, ComUtil.GetModifiers(methodInformation.parameters), CultureInfo.CurrentCulture, null); Adapter.SetReferences(objArray, methodInformation, arguments); return(obj2); } catch (TargetInvocationException exception) { CommandProcessorBase.CheckForSevereException(exception.InnerException); COMException innerException = exception.InnerException as COMException; if ((innerException == null) || (innerException.ErrorCode != -2147352573)) { throw; } } catch (COMException exception3) { if (exception3.ErrorCode != -2147352570) { throw; } } return(null); }
internal WMIMethodCacheEntry(string n, string cPath, MethodData mData) { this.name = n; this.classPath = cPath; this.methodInfoStructure = BaseWMIAdapter.GetMethodInformation(mData); this.methodDefinition = BaseWMIAdapter.GetMethodDefinition(mData); }
protected override object MethodInvoke(PSMethod method, object[] arguments) { ParameterInformation[] arguments1 = new ParameterInformation[arguments.Length]; for (int index = 0; index < arguments.Length; ++index) { arguments1[index] = new ParameterInformation(typeof(object), false, (object)null, false); } MethodInformation[] methods = new MethodInformation[1] { new MethodInformation(false, false, arguments1) }; object[] newArguments; Adapter.GetBestMethodAndArguments(method.Name, methods, arguments, out newArguments); DirectoryEntry baseObject = (DirectoryEntry)method.baseObject; Exception exception; try { return(baseObject.Invoke(method.Name, newArguments)); } catch (DirectoryServicesCOMException ex) { exception = (Exception)ex; } catch (TargetInvocationException ex) { exception = (Exception)ex; } catch (COMException ex) { exception = (Exception)ex; } return((DirectoryEntryAdapter.dotNetAdapter.GetDotNetMethod <PSMethod>(method.baseObject, method.name) ?? throw exception).Invoke(arguments)); }
internal static void CacheMethod( MethodInformation mi, object target, string methodName, object[] arguments, CallsiteCacheEntryFlags flags) { Type targetType = (flags & (CallsiteCacheEntryFlags.Static | CallsiteCacheEntryFlags.Constructor)) == CallsiteCacheEntryFlags.None ? target.GetType() : (Type)target; if (targetType == typeof(PSObject) || targetType == typeof(PSCustomObject)) { return; } CallsiteSignature signature = new CallsiteSignature(targetType, arguments, flags); CallsiteCacheEntry key = new CallsiteCacheEntry(methodName, signature); lock (Adapter.callsiteCache) { if (Adapter.callsiteCache.ContainsKey(key)) { return; } if (Adapter.callsiteCache.Count > 2048) { Adapter.callsiteCache.Clear(); } Adapter.callsiteCache[key] = mi; } }
/// <summary> /// Called after a non null return from GetMember to try to call /// the method with the arguments /// </summary> /// <param name="method">the non empty return from GetMethods</param> /// <param name="arguments">the arguments to use</param> /// <returns>the return value for the method</returns> protected override object MethodInvoke(PSMethod method, object[] arguments) { ParameterInformation[] parameters = new ParameterInformation[arguments.Length]; for (int i = 0; i < arguments.Length; i++) { parameters[i] = new ParameterInformation(typeof(System.Object), false, null, false); } MethodInformation[] methodInformation = new MethodInformation[1]; methodInformation[0] = new MethodInformation(false, false, parameters); object[] newArguments; GetBestMethodAndArguments(method.Name, methodInformation, arguments, out newArguments); DirectoryEntry entry = (DirectoryEntry)method.baseObject; // First try to invoke method on the native adsi object. If the method // call fails, try to invoke dotnet method with same name, if one available. // This will ensure dotnet methods are exposed for DE objects. // The problem is in GetMember<T>(), DE adapter cannot check if a requested // method is available as it doesn't have access to native adsi object's // method metadata. So GetMember<T> returns PSMethod assuming a method // is available. This behavior will never give a chance to dotnet adapter // to resolve method call. So the DE adapter owns calling dotnet method // if one available. Exception exception; try { return(entry.Invoke(method.Name, newArguments)); } catch (DirectoryServicesCOMException dse) { exception = dse; } catch (TargetInvocationException tie) { exception = tie; } catch (COMException ce) { exception = ce; } // this code is reached only on exception // check if there is a dotnet method, invoke the dotnet method if available PSMethod dotNetmethod = s_dotNetAdapter.GetDotNetMethod <PSMethod>(method.baseObject, method.name); if (null != dotNetmethod) { return(dotNetmethod.Invoke(arguments)); } // else throw exception; }
internal static MethodInformation Infer(MethodInformation genericMethod, Type[] argumentTypes) { MethodInfo method = (MethodInfo) genericMethod.method; MethodInfo info2 = Infer(method, argumentTypes, genericMethod.hasVarArgs); if (info2 != null) { return new MethodInformation(info2, 0); } return null; }
internal static MethodInformation Infer(MethodInformation genericMethod, Type[] argumentTypes) { MethodInfo method = (MethodInfo)genericMethod.method; MethodInfo info2 = Infer(method, argumentTypes, genericMethod.hasVarArgs); if (info2 != null) { return(new MethodInformation(info2, 0)); } return(null); }
internal static MethodInformation GetBestMethodAndArguments( string methodName, MethodInformation[] methods, object[] arguments, out object[] newArguments) { bool expandParamsOnBest; MethodInformation bestMethod = Adapter.FindBestMethod(methodName, methods, arguments, out expandParamsOnBest); newArguments = Adapter.GetMethodArgumentsBase(methodName, bestMethod.parameters, arguments, expandParamsOnBest); return(bestMethod); }
private Object AuxillaryInvokeMethod(ManagementObject obj, WMIMethodCacheEntry mdata, object[] arguments) { // Evaluate method and arguments object[] verifiedArguments; MethodInformation[] methods = new MethodInformation[1]; methods[0] = mdata.MethodInfoStructure; // This will convert Null Strings to Empty Strings GetBestMethodAndArguments(mdata.Name, methods, arguments, out verifiedArguments); ParameterInformation[] parameterList = mdata.MethodInfoStructure.parameters; // GetBestMethodAndArguments should fill verifiedArguments with // correct values (even if some values are not specified) tracer.WriteLine("Parameters found {0}. Arguments supplied {0}", parameterList.Length, verifiedArguments.Length); Diagnostics.Assert(parameterList.Length == verifiedArguments.Length, "The number of parameters and arguments should match"); // we should not cache inParameters as we are updating // inParameters object with argument values..Caching will // have side effects in this scenario like we have to clear // the values once the method is invoked. // Also caching MethodData occupies lot of memory compared to // caching string. ManagementClass mClass = CreateClassFrmObject(obj); ManagementBaseObject inParameters = mClass.GetMethodParameters(mdata.Name); for (int i = 0; i < parameterList.Length; i++) { // this cast should always succeed WMIParameterInformation pInfo = (WMIParameterInformation)parameterList[i]; // Should not convert null input arguments // GetBestMethodAndArguments converts null strings to empty strings // and also null ints to 0. But WMI providers do not like these // conversions. So dont convert input arguments if they are null. // We could have done this in the base adapter but the change would be // costly for other adpaters which dont mind the conversion. if ((i < arguments.Length) && (arguments[i] == null)) { verifiedArguments[i] = null; } inParameters[pInfo.Name] = verifiedArguments[i]; } return(InvokeManagementMethod(obj, mdata.Name, inParameters)); }
private static Type FindInterfaceForMethod(MethodInfo method, out MethodInfo methodToCall) { methodToCall = (MethodInfo)null; foreach (Type type in method.DeclaringType.GetInterfaces()) { MethodInfo method1 = type.GetMethod(method.Name, BindingFlags.Instance); if (method1 != null && MethodInformation.CompareMethodParameters(method1, method)) { methodToCall = method1; return(type); } } return((Type)null); }
internal static MethodInformation FindCachedMethod( Type targetType, string methodName, object[] arguments, CallsiteCacheEntryFlags flags) { if (targetType == typeof(PSObject) || targetType == typeof(PSCustomObject)) { return((MethodInformation)null); } CallsiteSignature signature = new CallsiteSignature(targetType, arguments, flags); CallsiteCacheEntry key = new CallsiteCacheEntry(methodName, signature); MethodInformation methodInformation = (MethodInformation)null; lock (Adapter.callsiteCache) Adapter.callsiteCache.TryGetValue(key, out methodInformation); return(methodInformation); }
/// <summary> /// Gets WMI method information. /// </summary> /// <param name="mData"></param> /// <returns></returns> /// <remarks> /// Decodes only input parameters. /// </remarks> internal static MethodInformation GetMethodInformation(MethodData mData) { Diagnostics.Assert(mData != null, "MethodData should not be null"); // Get Method parameters SortedList parameters = new SortedList(); UpdateParameters(mData.InParameters, parameters); // parameters is never null WMIParameterInformation[] pInfos = new WMIParameterInformation[parameters.Count]; if (parameters.Count > 0) { parameters.Values.CopyTo(pInfos, 0); } MethodInformation returnValue = new MethodInformation(false, true, pInfos); return(returnValue); }
private object AuxillaryInvokeMethod(ManagementObject obj, WMIMethodCacheEntry mdata, object[] arguments) { object[] objArray; MethodInformation[] methods = new MethodInformation[] { mdata.MethodInfoStructure }; Adapter.GetBestMethodAndArguments(mdata.Name, methods, arguments, out objArray); ParameterInformation[] parameters = mdata.MethodInfoStructure.parameters; Adapter.tracer.WriteLine("Parameters found {0}. Arguments supplied {0}", new object[] { parameters.Length, objArray.Length }); ManagementBaseObject methodParameters = CreateClassFrmObject(obj).GetMethodParameters(mdata.Name); for (int i = 0; i < parameters.Length; i++) { WMIParameterInformation information = (WMIParameterInformation)parameters[i]; if ((i < arguments.Length) && (arguments[i] == null)) { objArray[i] = null; } methodParameters[information.Name] = objArray[i]; } return(this.InvokeManagementMethod(obj, mdata.Name, methodParameters)); }
internal void SetValue(object target, object setValue, object[] arguments) { using (ComProperty.tracer.TraceMethod()) { object[] newArguments; MethodInformation methodAndArguments = Adapter.GetBestMethodAndArguments(this.Name, (MethodInformation[])ComUtil.GetMethodInformationArray(this.typeInfo, new Collection <int>() { this.hasSetterByRef ? this.setterByRefIndex : this.setterIndex }, true), arguments, out newArguments); Type type = target.GetType(); object[] objArray = new object[newArguments.Length + 1]; for (int index = 0; index < newArguments.Length; ++index) { objArray[index] = newArguments[index]; } objArray[newArguments.Length] = Adapter.PropertySetAndMethodArgumentConvertTo(setValue, this.Type, (IFormatProvider)CultureInfo.InvariantCulture); try { type.InvokeMember(this.name, BindingFlags.IgnoreCase | BindingFlags.SetProperty, (Binder)null, target, objArray, ComUtil.GetModifiers(methodAndArguments.parameters), CultureInfo.CurrentCulture, (string[])null); Adapter.SetReferences(objArray, methodAndArguments, arguments); } catch (TargetInvocationException ex) { CommandProcessorBase.CheckForSevereException(ex.InnerException); if (ex.InnerException is COMException innerException && innerException.ErrorCode == -2147352573) { return; } throw; } catch (COMException ex) { if (ex.ErrorCode == -2147352570) { return; } throw; } } }
protected override object MethodInvoke(PSMethod method, object[] arguments) { object[] objArray; Exception exception = null; ParameterInformation[] informationArray = new ParameterInformation[arguments.Length]; for (int i = 0; i < arguments.Length; i++) { informationArray[i] = new ParameterInformation(typeof(object), false, null, false); } MethodInformation[] methods = new MethodInformation[] { new MethodInformation(false, false, informationArray) }; Adapter.GetBestMethodAndArguments(method.Name, methods, arguments, out objArray); DirectoryEntry baseObject = (DirectoryEntry)method.baseObject; try { return(baseObject.Invoke(method.Name, objArray)); } #if !MONO catch (DirectoryServicesCOMException exception2) { exception = exception2; } #endif catch (TargetInvocationException exception3) { exception = exception3; } catch (COMException exception4) { exception = exception4; } PSMethod dotNetMethod = dotNetAdapter.GetDotNetMethod <PSMethod>(method.baseObject, method.name); if (dotNetMethod == null) { throw exception; } return(dotNetMethod.Invoke(arguments)); }
internal void SetValue(object target, object setValue, object[] arguments) { object[] objArray; Collection <int> methods = new Collection <int> { (this.hasSetterByRef != null) ? this.setterByRefIndex : this.setterIndex }; MethodInformation[] informationArray = ComUtil.GetMethodInformationArray(this.typeInfo, methods, true); MethodInformation methodInformation = Adapter.GetBestMethodAndArguments(this.Name, informationArray, arguments, out objArray); System.Type type = target.GetType(); object[] args = new object[objArray.Length + 1]; for (int i = 0; i < objArray.Length; i++) { args[i] = objArray[i]; } args[objArray.Length] = Adapter.PropertySetAndMethodArgumentConvertTo(setValue, this.Type, CultureInfo.InvariantCulture); try { type.InvokeMember(this.name, BindingFlags.SetProperty | BindingFlags.IgnoreCase, null, target, args, ComUtil.GetModifiers(methodInformation.parameters), CultureInfo.CurrentCulture, null); Adapter.SetReferences(args, methodInformation, arguments); } catch (TargetInvocationException exception) { CommandProcessorBase.CheckForSevereException(exception.InnerException); COMException innerException = exception.InnerException as COMException; if ((innerException == null) || (innerException.ErrorCode != -2147352573)) { throw; } } catch (COMException exception3) { if (exception3.ErrorCode != -2147352570) { throw; } } }
internal object GetValue(object target, object[] arguments) { using (ComProperty.tracer.TraceMethod()) { Type type = target.GetType(); try { object[] newArguments; MethodInformation methodAndArguments = Adapter.GetBestMethodAndArguments(this.Name, (MethodInformation[])ComUtil.GetMethodInformationArray(this.typeInfo, new Collection <int>() { this.getterIndex }, false), arguments, out newArguments); object obj = type.InvokeMember(this.name, BindingFlags.IgnoreCase | BindingFlags.GetProperty, (Binder)null, target, newArguments, ComUtil.GetModifiers(methodAndArguments.parameters), CultureInfo.CurrentCulture, (string[])null); Adapter.SetReferences(newArguments, methodAndArguments, arguments); return(obj); } catch (TargetInvocationException ex) { CommandProcessorBase.CheckForSevereException(ex.InnerException); if (ex.InnerException is COMException innerException) { if (innerException.ErrorCode == -2147352573) { goto label_8; } } throw; } catch (COMException ex) { if (ex.ErrorCode != -2147352570) { throw; } } label_8: return((object)null); } }
internal static object CallMethod(IScriptExtent errorPosition, object target, string methodName, PSMethodInvocationConstraints invocationConstraints, object[] paramArray, bool callStatic, object valueToSet) { PSMethodInfo staticCLRMember = null; MethodInformation methodInformation = null; object obj2 = null; PSObject obj3 = null; Type type; object obj4; if (LanguagePrimitives.IsNull(target)) { throw InterpreterError.NewInterpreterException(methodName, typeof(RuntimeException), errorPosition, "InvokeMethodOnNull", ParserStrings.InvokeMethodOnNull, new object[0]); } obj2 = PSObject.Base(target); obj3 = PSObject.AsPSObject(target); CallsiteCacheEntryFlags none = CallsiteCacheEntryFlags.None; if (callStatic) { none |= CallsiteCacheEntryFlags.Static; type = (Type)obj2; } else { type = obj2.GetType(); } if (valueToSet != AutomationNull.Value) { none |= CallsiteCacheEntryFlags.ParameterizedSetter; } if (!obj3.isDeserialized) { methodInformation = Adapter.FindCachedMethod(type, methodName, invocationConstraints, paramArray, none); } if (methodInformation == null) { if (callStatic) { staticCLRMember = PSObject.GetStaticCLRMember(target, methodName) as PSMethod; } else { staticCLRMember = obj3.Members[methodName] as PSMethodInfo; } if (staticCLRMember == null) { string fullName = null; if (callStatic) { fullName = type.FullName; } else { fullName = GetTypeFullName(target); } if (valueToSet == AutomationNull.Value) { throw InterpreterError.NewInterpreterException(methodName, typeof(RuntimeException), errorPosition, "MethodNotFound", ParserStrings.MethodNotFound, new object[] { fullName, methodName }); } throw InterpreterError.NewInterpreterException(methodName, typeof(RuntimeException), errorPosition, "ParameterizedPropertyAssignmentFailed", ParserStrings.ParameterizedPropertyAssignmentFailed, new object[] { fullName, methodName }); } } try { if (methodInformation != null) { object[] objArray; PSObject.memberResolution.WriteLine("cache hit, Calling Method: {0}", new object[] { methodInformation.methodDefinition }); if (valueToSet != AutomationNull.Value) { DotNetAdapter.ParameterizedPropertyInvokeSet(methodName, obj2, valueToSet, new MethodInformation[] { methodInformation }, paramArray, false); return(valueToSet); } MethodInformation[] methods = new MethodInformation[] { methodInformation }; Adapter.GetBestMethodAndArguments(methodName, methods, paramArray, out objArray); return(DotNetAdapter.AuxiliaryMethodInvoke(obj2, objArray, methodInformation, paramArray)); } if (valueToSet != AutomationNull.Value) { PSParameterizedProperty property = staticCLRMember as PSParameterizedProperty; if (property == null) { throw InterpreterError.NewInterpreterException(methodName, typeof(RuntimeException), errorPosition, "ParameterizedPropertyAssignmentFailed", ParserStrings.ParameterizedPropertyAssignmentFailed, new object[] { GetTypeFullName(target), methodName }); } property.InvokeSet(valueToSet, paramArray); return(valueToSet); } PSMethod method = staticCLRMember as PSMethod; if (method != null) { return(method.Invoke(invocationConstraints, paramArray)); } obj4 = staticCLRMember.Invoke(paramArray); } catch (MethodInvocationException exception) { if (exception.ErrorRecord.InvocationInfo == null) { exception.ErrorRecord.SetInvocationInfo(new InvocationInfo(null, errorPosition)); } throw; } catch (RuntimeException exception2) { if (exception2.ErrorRecord.InvocationInfo == null) { exception2.ErrorRecord.SetInvocationInfo(new InvocationInfo(null, errorPosition)); } throw; } catch (FlowControlException) { throw; } catch (ScriptCallDepthException) { throw; } catch (Exception exception3) { CommandProcessorBase.CheckForSevereException(exception3); throw InterpreterError.NewInterpreterExceptionByMessage(typeof(RuntimeException), errorPosition, exception3.Message, "MethodInvocationException", exception3); } return(obj4); }
private MethodInformation.MethodInvoker GetMethodInvoker(MethodInfo method) { bool flag1 = false; bool flag2 = false; bool flag3 = false; MethodInfo methodToCall = method; DynamicMethod dynamicMethod = new DynamicMethod(method.Name, typeof(object), new Type[2] { typeof(object), typeof(object[]) }, typeof(Adapter).Module, true); ILGenerator ilGenerator = dynamicMethod.GetILGenerator(); ParameterInfo[] parameters = method.GetParameters(); int length = 0; if (!method.IsStatic && method.DeclaringType.IsValueType && !method.IsVirtual) { flag1 = true; ++length; } foreach (ParameterInfo parameterInfo in parameters) { if (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef) { flag2 = true; ++length; } } LocalBuilder[] localBuilderArray = (LocalBuilder[])null; if (length > 0) { if (flag2 && method.ReturnType != typeof(void)) { ++length; flag3 = true; } localBuilderArray = new LocalBuilder[length]; int index = 0; if (flag1) { Type declaringType = method.DeclaringType; localBuilderArray[index] = ilGenerator.DeclareLocal(declaringType); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Unbox_Any, declaringType); ilGenerator.Emit(OpCodes.Stloc, localBuilderArray[index]); ++index; } for (int c = 0; c < parameters.Length; ++c) { Type type = parameters[c].ParameterType; if (parameters[c].IsOut || type.IsByRef) { if (type.IsByRef) { type = type.GetElementType(); } localBuilderArray[index] = ilGenerator.DeclareLocal(type); ilGenerator.Emit(OpCodes.Ldarg_1); MethodInformation.EmitLdc(ilGenerator, c); ilGenerator.Emit(OpCodes.Ldelem_Ref); if (type.IsValueType) { ilGenerator.Emit(OpCodes.Unbox_Any, type); } else if (type != typeof(object)) { ilGenerator.Emit(OpCodes.Castclass, type); } ilGenerator.Emit(OpCodes.Stloc, localBuilderArray[index]); ++index; } } if (flag3) { localBuilderArray[index] = ilGenerator.DeclareLocal(method.ReturnType); } } int index1 = 0; if (!method.IsStatic) { if (method.DeclaringType.IsValueType) { if (method.IsVirtual) { Type interfaceForMethod = MethodInformation.FindInterfaceForMethod(method, out methodToCall); if (interfaceForMethod == null) { this.useReflection = true; return((MethodInformation.MethodInvoker)null); } ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Castclass, interfaceForMethod); } else { ilGenerator.Emit(OpCodes.Ldloca, localBuilderArray[index1]); ++index1; } } else { ilGenerator.Emit(OpCodes.Ldarg_0); } } for (int c = 0; c < parameters.Length; ++c) { Type parameterType = parameters[c].ParameterType; if (parameterType.IsByRef) { ilGenerator.Emit(OpCodes.Ldloca, localBuilderArray[index1]); ++index1; } else if (parameters[c].IsOut) { ilGenerator.Emit(OpCodes.Ldloc, localBuilderArray[index1]); ++index1; } else { ilGenerator.Emit(OpCodes.Ldarg_1); MethodInformation.EmitLdc(ilGenerator, c); ilGenerator.Emit(OpCodes.Ldelem_Ref); if (parameterType.IsValueType) { ilGenerator.Emit(OpCodes.Unbox_Any, parameterType); } else if (parameterType != typeof(object)) { ilGenerator.Emit(OpCodes.Castclass, parameterType); } } } if (method.IsStatic) { ilGenerator.EmitCall(OpCodes.Call, methodToCall, (Type[])null); } else { ilGenerator.EmitCall(OpCodes.Callvirt, methodToCall, (Type[])null); } if (flag3) { ilGenerator.Emit(OpCodes.Stloc, localBuilderArray[localBuilderArray.Length - 1]); } if (flag2) { int index2 = flag1 ? 1 : 0; for (int c = 0; c < parameters.Length; ++c) { Type cls = parameters[c].ParameterType; if (parameters[c].IsOut || cls.IsByRef) { if (cls.IsByRef) { cls = cls.GetElementType(); } ilGenerator.Emit(OpCodes.Ldarg_1); MethodInformation.EmitLdc(ilGenerator, c); ilGenerator.Emit(OpCodes.Ldloc, localBuilderArray[index2]); if (cls.IsValueType) { ilGenerator.Emit(OpCodes.Box, cls); } ilGenerator.Emit(OpCodes.Stelem_Ref); ++index2; } } } if (method.ReturnType == typeof(void)) { ilGenerator.Emit(OpCodes.Ldnull); } else { if (flag3) { ilGenerator.Emit(OpCodes.Ldloc, localBuilderArray[localBuilderArray.Length - 1]); } if (method.ReturnType.IsValueType) { ilGenerator.Emit(OpCodes.Box, method.ReturnType); } } ilGenerator.Emit(OpCodes.Ret); return((MethodInformation.MethodInvoker)dynamicMethod.CreateDelegate(typeof(MethodInformation.MethodInvoker))); }
internal static MethodInformation FindBestMethod( string methodName, MethodInformation[] methods, object[] arguments, out bool expandParamsOnBest) { if (methods.Length == 1 && !methods[0].hasVarArgs && methods[0].parameters.Length == arguments.Length) { expandParamsOnBest = false; return(methods[0]); } List <Adapter.OverloadCandidate> candidates = new List <Adapter.OverloadCandidate>(); for (int index1 = 0; index1 < methods.Length; ++index1) { MethodInformation method = methods[index1]; if (!method.isGeneric) { ParameterInformation[] parameters = method.parameters; if (arguments.Length != parameters.Length) { if (arguments.Length > parameters.Length) { if (!method.hasVarArgs) { continue; } } else if (method.hasOptional || method.hasVarArgs && arguments.Length + 1 == parameters.Length) { if (method.hasOptional) { int num = 0; for (int index2 = 0; index2 < parameters.Length; ++index2) { if (parameters[index2].isOptional) { ++num; } } if (arguments.Length + num < parameters.Length) { continue; } } } else { continue; } } Adapter.OverloadCandidate overloadCandidate = new Adapter.OverloadCandidate(method, arguments.Length); for (int index2 = 0; overloadCandidate != null && index2 < parameters.Length; ++index2) { ParameterInformation parameterInformation = parameters[index2]; if (!parameterInformation.isOptional || arguments.Length > index2) { if (parameterInformation.isParamArray) { Type elementType = parameterInformation.parameterType.GetElementType(); if (parameters.Length == arguments.Length) { ConversionRank argumentConversionRank1 = Adapter.GetArgumentConversionRank(arguments[index2], parameterInformation.parameterType); ConversionRank argumentConversionRank2 = Adapter.GetArgumentConversionRank(arguments[index2], elementType); if (argumentConversionRank2 > argumentConversionRank1) { overloadCandidate.expandedParameters = Adapter.ExpandParameters(arguments.Length, parameters, elementType); overloadCandidate.conversionRanks[index2] = argumentConversionRank2; } else { overloadCandidate.conversionRanks[index2] = argumentConversionRank1; } if (overloadCandidate.conversionRanks[index2] == ConversionRank.None) { overloadCandidate = (Adapter.OverloadCandidate)null; } } else { for (int index3 = index2; index3 < arguments.Length; ++index3) { overloadCandidate.conversionRanks[index3] = Adapter.GetArgumentConversionRank(arguments[index3], elementType); if (overloadCandidate.conversionRanks[index3] == ConversionRank.None) { overloadCandidate = (Adapter.OverloadCandidate)null; break; } } if (overloadCandidate != null) { overloadCandidate.expandedParameters = Adapter.ExpandParameters(arguments.Length, parameters, elementType); } } } else { overloadCandidate.conversionRanks[index2] = Adapter.GetArgumentConversionRank(arguments[index2], parameterInformation.parameterType); if (overloadCandidate.conversionRanks[index2] == ConversionRank.None) { overloadCandidate = (Adapter.OverloadCandidate)null; } } } else { break; } } if (overloadCandidate != null) { candidates.Add(overloadCandidate); } } } if (candidates.Count == 0) { throw new MethodException("MethodCountCouldNotFindBest", (Exception)null, "ExtendedTypeSystem", "MethodArgumentCountException", new object[2] { (object)methodName, (object)arguments.Length }); } Adapter.OverloadCandidate overloadCandidate1 = candidates.Count != 1 ? Adapter.FindBestCandidate(candidates, arguments) : candidates[0]; if (overloadCandidate1 != null) { expandParamsOnBest = overloadCandidate1.expandedParameters != null; return(overloadCandidate1.method); } throw new MethodException("MethodCountCouldNotFindBest", (Exception)null, "ExtendedTypeSystem", "MethodAmbiguousException", new object[2] { (object)methodName, (object)arguments.Length }); }
internal OverloadCandidate(MethodInformation method, int argCount) { this.method = method; this.parameters = method.parameters; this.conversionRanks = new ConversionRank[argCount]; }