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);
                }
            }
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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);
        }