DbgDotNetValueResult CallCore(DbgDotNetValue obj, bool isCallvirt, DmdMethodBase method, ILValue[] arguments) { var options = isCallvirt ? DotNetClassHookCallOptions.IsCallvirt : DotNetClassHookCallOptions.None; foreach (var anyHook in anyClassHooks) { var res = anyHook.Call(options, obj, method, arguments); if (res != null) { return(new DbgDotNetValueResult(res, valueIsException: false)); } } var type = method.DeclaringType; if (type.IsConstructedGenericType) { type = type.GetGenericTypeDefinition(); } var typeName = DmdTypeName.Create(type); if (classHooks.TryGetValue(typeName, out var hook)) { if (DmdWellKnownTypeUtils.TryGetWellKnownType(typeName, out var wellKnownType)) { if (type != type.AppDomain.GetWellKnownType(wellKnownType, isOptional: true)) { hook = null; } } if (hook != null) { var res = hook.Call(options, obj, method, arguments); if (res != null) { return(new DbgDotNetValueResult(res, valueIsException: false)); } } } if (!canFuncEval) { throw new InterpreterMessageException(PredefinedEvaluationErrorMessages.FuncEvalDisabled); } return(runtime.Call(context, frame, obj, method, Convert(arguments, method.GetMethodSignature().GetParameterTypes()), cancellationToken)); }
public DebuggerRuntimeImpl(DbgObjectIdService dbgObjectIdService, IDbgDotNetRuntime runtime, int pointerSize, DotNetClassHookFactory[] dotNetClassHookFactories) { if (dotNetClassHookFactories == null) { throw new ArgumentNullException(nameof(dotNetClassHookFactories)); } this.dbgObjectIdService = dbgObjectIdService ?? throw new ArgumentNullException(nameof(dbgObjectIdService)); this.runtime = runtime ?? throw new ArgumentNullException(nameof(runtime)); valuesToDispose = new List <DbgDotNetValue>(); interpreterLocalsProvider = new InterpreterLocalsProvider(this); PointerSize = pointerSize; var anyClassHooksList = new List <DotNetClassHook>(); classHooks = new Dictionary <DmdTypeName, DotNetClassHook>(DmdTypeNameEqualityComparer.Instance); foreach (var factory in dotNetClassHookFactories) { foreach (var info in factory.Create(this)) { Debug.Assert(info.Hook != null); if (info.WellKnownType == null && info.TypeName == null) { anyClassHooksList.Add(info.Hook); } else { DmdTypeName typeName; if (info.WellKnownType != null) { typeName = DmdWellKnownTypeUtils.GetTypeName(info.WellKnownType.Value); } else { Debug.Assert(info.TypeName != null); typeName = info.TypeName.Value; } Debug.Assert(!classHooks.ContainsKey(typeName)); classHooks[typeName] = info.Hook; } } } anyClassHooks = anyClassHooksList.ToArray(); }