Beispiel #1
0
        public void Execute(SysReflection.MethodBase aStartMethod)
        {
            if (aStartMethod == null)
            {
                throw new ArgumentNullException("aStartMethod");
            }
            // TODO: Investigate using MS CCI
            // Need to check license, as well as in profiler
            // http://cciast.codeplex.com/

            #region Description
            // Methodology
            //
            // Ok - we've done the scanner enough times to know it needs to be
            // documented super well so that future changes won't inadvertently
            // break undocumented and unseen requirements.
            //
            // We've tried many approaches including recursive and additive scanning.
            // They typically end up being inefficient, overly complex, or both.
            //
            // -We would like to scan all types/methods so we can plug them.
            // -But we can't scan them until we plug them, because we will scan things
            // that plugs would remove/change the paths of.
            // -Plugs may also call methods which are also plugged.
            // -We cannot resolve plugs ahead of time but must do on the fly during
            // scanning.
            // -TODO: Because we do on the fly resolution, we need to add explicit
            // checking of plug classes and err when public methods are found that
            // do not resolve. Maybe we can make a list and mark, or rescan. Can be done
            // later or as an optional auditing step.
            //
            // This why in the past we had repetitive scans.
            //
            // Now we focus on more passes, but simpler execution. In the end it should
            // be eaiser to optmize and yield overall better performance. Most of the
            // passes should be low overhead versus an integrated system which often
            // would need to reiterate over items multiple times. So we do more loops on
            // with less repetitive analysis, instead of fewer loops but more repetition.
            //
            // -Locate all plug classes
            // -Scan from entry point collecting all types and methods while checking
            // for and following plugs
            // -For each type
            //    -Include all ancestors
            //    -Include all static constructors
            // -For each virtual method
            //    -Scan overloads in descendants until IsFinal, IsSealed or end
            //    -Scan base in ancestors until top or IsAbstract
            // -Go to scan types again, until no new ones found.
            // -Because the virtual method scanning will add to the list as it goes, maintain
            //  2 lists.
            //    -Known Types and Methods
            //    -Types and Methods in Queue - to be scanned
            // -Finally, do compilation
            #endregion
            mPlugManager.FindPlugImpls();
            // Now that we found all plugs, scan them.
            // We have to scan them after we find all plugs, because
            // plugs can use other plugs
            mPlugManager.ScanFoundPlugs();
            foreach (var xPlug in mPlugManager.PlugImpls)
            {
                CompilerHelpers.Debug($"Plug found: '{xPlug.Key.FullName}'");
            }

            ILOp.mPlugManager = mPlugManager;

            // Pull in extra implementations, GC etc.
            Queue(RuntimeEngineRefs.InitializeApplicationRef, null, "Explicit Entry");
            Queue(RuntimeEngineRefs.FinalizeApplicationRef, null, "Explicit Entry");
            //Queue(typeof(CosmosAssembler).GetMethod("PrintException"), null, "Explicit Entry");
            Queue(VTablesImplRefs.SetMethodInfoRef, null, "Explicit Entry");
            Queue(VTablesImplRefs.IsInstanceRef, null, "Explicit Entry");
            Queue(VTablesImplRefs.SetTypeInfoRef, null, "Explicit Entry");
            Queue(VTablesImplRefs.GetMethodAddressForTypeRef, null, "Explicit Entry");
            Queue(GCImplementationRefs.IncRefCountRef, null, "Explicit Entry");
            Queue(GCImplementationRefs.DecRefCountRef, null, "Explicit Entry");
            Queue(GCImplementationRefs.AllocNewObjectRef, null, "Explicit Entry");
            // for now, to ease runtime exception throwing
            Queue(typeof(ExceptionHelper).GetMethod("ThrowNotImplemented", BindingFlags.Static | BindingFlags.Public, null, new Type[] { typeof(string) }, null), null, "Explicit Entry");
            Queue(typeof(ExceptionHelper).GetMethod("ThrowOverflow", BindingFlags.Static | BindingFlags.Public, null, new Type[] { }, null), null, "Explicit Entry");
            Queue(RuntimeEngineRefs.InitializeApplicationRef, null, "Explicit Entry");
            Queue(RuntimeEngineRefs.FinalizeApplicationRef, null, "Explicit Entry");
            // register system types:
            Queue(typeof(Array), null, "Explicit Entry");
            Queue(typeof(Array).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null), null, "Explicit Entry");

            var xThrowHelper = Type.GetType("System.ThrowHelper", true);
            Queue(xThrowHelper.GetMethod("ThrowInvalidOperationException", BindingFlags.NonPublic | BindingFlags.Static), null, "Explicit Entry");

            Queue(typeof(MulticastDelegate).GetMethod("GetInvocationList"), null, "Explicit Entry");
            Queue(ExceptionHelperRefs.CurrentExceptionRef, null, "Explicit Entry");
            //System_Delegate____System_MulticastDelegate_GetInvocationList__

            // Start from entry point of this program
            Queue(aStartMethod, null, "Entry Point");

            ScanQueue();
            UpdateAssemblies();
            Assemble();

            mAsmblr.EmitEntrypoint(aStartMethod);
        }