public void AddCompilationRoots(IRootingServiceProvider rootProvider)
        {
            TypeDesc owningType = _module.GetGlobalModuleType();
            NativeLibraryStartupMethod nativeLibStartupCode = new NativeLibraryStartupMethod(owningType, _libraryInitializers);

            rootProvider.AddCompilationRoot(nativeLibStartupCode, "Startup Code Main Method", ManagedEntryPointMethodName);
        }
Exemple #2
0
        public int CompareTo(PInvokeModuleData other, CompilerComparer comparer)
        {
            int result = StringComparer.Ordinal.Compare(ModuleName, other.ModuleName);

            if (result != 0)
            {
                return(result);
            }

            result = comparer.Compare(DeclaringModule.GetGlobalModuleType(),
                                      other.DeclaringModule.GetGlobalModuleType());
            if (result != 0)
            {
                return(result);
            }

            return(Nullable.Compare(DllImportSearchPath, other.DllImportSearchPath));
        }
 internal static void AddDependenciesDueToModuleUse(ref DependencyList dependencyList, NodeFactory factory, ModuleDesc module)
 {
     dependencyList ??= new DependencyList();
     if (module.GetGlobalModuleType().GetStaticConstructor() is MethodDesc moduleCctor)
     {
         dependencyList.Add(factory.MethodEntrypoint(moduleCctor), "Module with a static constructor");
     }
     factory.MetadataManager.GetDependenciesDueToModuleUse(ref dependencyList, factory, module);
 }
Exemple #4
0
        public override IEnumerable <DependencyListEntry> GetStaticDependencies(NodeFactory factory)
        {
            DependencyList dependencies = new DependencyList();

            // Global module type always generates metadata because it's really convenient to
            // have something in an assembly that always generates metadata.
            dependencies.Add(factory.TypeMetadata(_module.GetGlobalModuleType()), "Global module type");

            CustomAttributeBasedDependencyAlgorithm.AddDependenciesDueToCustomAttributes(ref dependencies, factory, (EcmaAssembly)_module);

            return(dependencies);
        }
 public void RootModuleMetadata(ModuleDesc module, string reason)
 {
     // RootModuleMetadata is kind of a hack - this is pretty much only used to force include
     // type forwarders from assemblies metadata generator would normally not look at.
     // This will go away when the temporary RD.XML parser goes away.
     if (_factory.MetadataManager is UsageBasedMetadataManager mdManager)
     {
         // If we wouldn't generate metadata for the global module type, don't root the metadata at all.
         // Global module type always gets metadata and if we're not generating it, this is not the right
         // compilation unit (we're likely doing multifile).
         if (mdManager.CanGenerateMetadata(module.GetGlobalModuleType()))
         {
             _rootAdder(_factory.ModuleMetadata(module), reason);
         }
     }
 }
        /// <summary>
        /// Gets a stub that can be used to reflection-invoke a method with a given signature.
        /// </summary>
        public sealed override MethodDesc GetCanonicalReflectionInvokeStub(MethodDesc method)
        {
            TypeSystemContext context = method.Context;
            var sig = method.Signature;

            // Get a generic method that can be used to invoke method with this shape.
            MethodDesc thunk;
            var        lookupSig = new DynamicInvokeMethodSignature(sig);

            if (!_dynamicInvokeThunks.TryGetValue(lookupSig, out thunk))
            {
                thunk = new DynamicInvokeMethodThunk(_generatedAssembly.GetGlobalModuleType(), lookupSig);
                _dynamicInvokeThunks.Add(lookupSig, thunk);
            }

            return(InstantiateCanonicalDynamicInvokeMethodForMethod(thunk, method));
        }
Exemple #7
0
        public override MethodIL EmitIL()
        {
            ILEmitter    emitter    = new ILEmitter();
            ILCodeStream codeStream = emitter.NewCodeStream();

            codeStream.MarkDebuggerStepThroughPoint();

            // Allow the class library to run explicitly ordered class constructors first thing in start-up.
            if (_libraryInitializers != null)
            {
                foreach (MethodDesc method in _libraryInitializers)
                {
                    codeStream.Emit(ILOpcode.call, emitter.NewToken(method));
                }
            }

            MetadataType startup = Context.GetHelperType("StartupCodeHelpers");

            // Initialize command line args if the class library supports this
            string initArgsName = (Context.Target.OperatingSystem == TargetOS.Windows)
                                ? "InitializeCommandLineArgsW"
                                : "InitializeCommandLineArgs";
            MethodDesc initArgs = startup.GetMethod(initArgsName, null);

            if (initArgs != null)
            {
                codeStream.Emit(ILOpcode.ldarg_0); // argc
                codeStream.Emit(ILOpcode.ldarg_1); // argv
                codeStream.Emit(ILOpcode.call, emitter.NewToken(initArgs));
            }

            // Initialize the entrypoint assembly if the class library supports this
            MethodDesc initEntryAssembly = startup.GetMethod("InitializeEntryAssembly", null);

            if (initEntryAssembly != null)
            {
                ModuleDesc entrypointModule = ((MetadataType)_mainMethod.WrappedMethod.OwningType).Module;
                codeStream.Emit(ILOpcode.ldtoken, emitter.NewToken(entrypointModule.GetGlobalModuleType()));
                codeStream.Emit(ILOpcode.call, emitter.NewToken(initEntryAssembly));
            }

            // Call program Main
            if (_mainMethod.Signature.Length > 0)
            {
                // TODO: better exception
                if (initArgs == null)
                {
                    throw new Exception("Main() has parameters, but the class library doesn't support them");
                }

                codeStream.Emit(ILOpcode.call, emitter.NewToken(startup.GetKnownMethod("GetMainMethodArguments", null)));
            }

            codeStream.MarkDebuggerStepInPoint();
            codeStream.Emit(ILOpcode.call, emitter.NewToken(_mainMethod));

            MethodDesc setLatchedExitCode = startup.GetMethod("SetLatchedExitCode", null);
            MethodDesc shutdown           = startup.GetMethod("Shutdown", null);

            // The class library either supports "advanced shutdown", or doesn't. No half-implementations allowed.
            Debug.Assert((setLatchedExitCode != null) == (shutdown != null));

            if (setLatchedExitCode != null)
            {
                // If the main method has a return value, save it
                if (!_mainMethod.Signature.ReturnType.IsVoid)
                {
                    codeStream.Emit(ILOpcode.call, emitter.NewToken(setLatchedExitCode));
                }

                // Ask the class library to shut down and return exit code.
                codeStream.Emit(ILOpcode.call, emitter.NewToken(shutdown));
            }
            else
            {
                // This is a class library that doesn't have SetLatchedExitCode/Shutdown.
                // If the main method returns void, we simply use 0 exit code.
                if (_mainMethod.Signature.ReturnType.IsVoid)
                {
                    codeStream.EmitLdc(0);
                }
            }

            codeStream.Emit(ILOpcode.ret);

            return(emitter.Link(this));
        }
Exemple #8
0
 public void TestModuleType()
 {
     Assert.True(_testModule.GetGlobalModuleType().IsModuleType);
 }