private void ScanTypeForCilMethods(Type item, Type mappedType) { var methodsToScan = new List <MethodBase>(); methodsToScan.AddRange(item.GetMethods()); methodsToScan.AddRange(item.GetConstructors()); foreach (var methodInfo in methodsToScan) { var methodNativeDescription = methodInfo.GetCustomAttribute <CilMethodAttribute>(); if (methodNativeDescription == null) { continue; } var interpreter = methodInfo.Register(); var iKey = interpreter.ToKey(item); iKey.MapTypes(MappedTypes); SupportedMethods[iKey] = interpreter; MetaLinker.Interpret(interpreter, this); var dependencies = MetaLinker.ComputeDependencies(methodInfo); foreach (var dependency in dependencies) { MetaLinker.Interpret(dependency, this); } } }
public static HashSet <Type> GetTypesClosure(List <MethodInterpreter> methodList, out bool foundNewMethods, ProgramClosure programClosure, CrRuntimeLibrary crRuntime) { var typesSet = ScanMethodParameters(methodList, crRuntime); foundNewMethods = false; var resultTypes = BuildScannedDictionaryFromTypesAndInstructions(typesSet, crRuntime); var methodDict = methodList.ToDictionary(method => method.Method.Register(crRuntime).ToKey()); var virtMethods = methodList.Where(m => m.Method.IsVirtual).ToArray(); foreach (var virt in virtMethods) { var baseClass = virt.Method.DeclaringType; var methodName = virt.Method.Name; var methodArgs = virt.Method.GetParameters().Select(par => par.ParameterType).ToArray(); foreach (var type in resultTypes) { if (!type.IsSubclassOf(baseClass)) { continue; } var implMethod = type.GetMethod(methodName, methodArgs); if (methodDict.ContainsKey(implMethod.Register(crRuntime).ToKey())) { continue; } var implInterpreter = implMethod.Register(); MetaLinker.Interpret(implInterpreter, crRuntime); methodList.Add(implInterpreter); foundNewMethods = true; } } return(resultTypes); }
public static MethodInterpreter CreateLinkerFromEntryPoint(this MethodInfo definition, ProgramClosure programClosure) { var methodInterpreter = definition.Register(); MetaLinker.Interpret(methodInterpreter, programClosure.Runtime); OptimizeMethods(LinkerInterpretersTable.Methods); var foundMethodCount = 1; var canContinue = true; while (canContinue) { var dependencies = methodInterpreter.GetMethodClosure(programClosure.Runtime); canContinue = foundMethodCount != dependencies.Count; foundMethodCount = dependencies.Count; foreach (var interpreter in dependencies) { MetaLinker.Interpret(interpreter, programClosure.Runtime); } OptimizeMethods(LinkerInterpretersTable.Methods); } return(methodInterpreter); }
public static ClosureResult BuildClosureForEntry(MethodInterpreter entryInterpreter, ProgramClosure programClosure) { var result = new ClosureResult(); var methodInterpreters = new Dictionary <MethodInterpreterKey, MethodInterpreter>(); methodInterpreters.Clear(); methodInterpreters[entryInterpreter.ToKey()] = entryInterpreter; MetaLinker.Interpret(entryInterpreter, programClosure.Runtime); var canContinue = true; var dependencies = entryInterpreter.GetMethodClosure(programClosure.Runtime); while (canContinue) { foreach (var interpreter in dependencies) { MetaLinker.Interpret(interpreter, programClosure.Runtime); } foreach (var dependency in dependencies) { methodInterpreters[dependency.ToKey()] = dependency; } result.MethodInterpreters = methodInterpreters; var foundMethodCount = methodInterpreters.Count; dependencies = methodInterpreters.Values.ToList(); bool foundNewMethods; result.UsedTypes = new HashSet <Type>(GetTypesClosure(dependencies, out foundNewMethods, programClosure, programClosure.Runtime)); foreach (var dependency in dependencies) { methodInterpreters[dependency.ToKey()] = dependency; } foreach (var interpreter in methodInterpreters.Values) { interpreter.Process(programClosure.Runtime); } dependencies = methodInterpreters.Values.ToList().GetMultiMethodsClosure(programClosure.Runtime); canContinue = foundMethodCount != dependencies.Count; } return(result); }
public static HashSet <Type> GetTypesClosure(List <MethodInterpreter> methodList, out bool foundNewMethods, ProgramClosure programClosure, CrRuntimeLibrary crRuntime) { var typesSet = ScanMethodParameters(methodList, crRuntime); //For struct types we need to add them separately foreach (var methodInterpreter in methodList) { foreach (var operation in methodInterpreter.MidRepresentation.LocalOperations) { if (operation is Assignment) { var type = (operation as Assignment).AssignedTo.FixedType.ClrType; if (!typesSet.Contains(type) && !type.IsByRef) { typesSet.Add(type); } } if (operation is RefAssignment) { var type = (operation as RefAssignment).Left.FixedType.ClrType; if (!typesSet.Contains(type) && !type.IsByRef) { typesSet.Add(type); } } } } foundNewMethods = false; var resultTypes = BuildScannedDictionaryFromTypesAndInstructions(typesSet, crRuntime); var methodDict = methodList.ToDictionary(method => method.Method.Register(crRuntime).ToKey()); var virtMethods = methodList.Where(m => m.Method.IsVirtual).ToArray(); foreach (var virt in virtMethods) { var baseClass = virt.Method.DeclaringType; var methodName = virt.Method.Name; var methodArgs = virt.Method.GetParameters().Select(par => par.ParameterType).ToArray(); foreach (var type in resultTypes) { var hasinterface = false;//TODO: for some reason I cannot use .Contains / Linq here ? foreach (var @interface in type.GetInterfaces()) { if (@interface == baseClass) { hasinterface = true; // methodName = baseClass.Name +"."+methodName; break; } } if ((!(type.IsSubclassOf(baseClass) || hasinterface))) { continue; } MethodInfo implMethod; if (!hasinterface) { implMethod = type.GetMethod(methodName, methodArgs); } else { implMethod = type.GetInterfaceMap(baseClass) .InterfaceMethods.Where(m => m.Name == methodName && (!m.GetParameters().Select(j => j.ParameterType).Except(methodArgs).Any())).FirstOrDefault(); } if (methodDict.ContainsKey(implMethod.Register(crRuntime).ToKey())) { continue; } var implInterpreter = implMethod.Register(); MetaLinker.Interpret(implInterpreter, crRuntime); methodList.Add(implInterpreter); foundNewMethods = true; } } return(resultTypes); }