public void AddCompilationRoots(IRootingServiceProvider rootProvider) { TypeDesc owningType = _module.GetGlobalModuleType(); NativeLibraryStartupMethod nativeLibStartupCode = new NativeLibraryStartupMethod(owningType, _libraryInitializers); rootProvider.AddCompilationRoot(nativeLibStartupCode, "Startup Code Main Method", ManagedEntryPointMethodName); }
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); }
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)); }
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)); }
public void TestModuleType() { Assert.True(_testModule.GetGlobalModuleType().IsModuleType); }