Beispiel #1
0
        /// <summary>
        /// Gets the type of System.Type descendant that implements runtime types.
        /// </summary>
        public virtual TypeDesc GetTypeOfRuntimeType()
        {
            ModuleDesc reflectionCoreModule = TypeSystemContext.GetModuleForSimpleName("System.Private.Reflection.Core", false);

            if (reflectionCoreModule != null)
            {
                return(reflectionCoreModule.GetKnownType("System.Reflection.Runtime.TypeInfos", "RuntimeTypeInfo"));
            }

            return(null);
        }
Beispiel #2
0
        public override MethodIL EmitIL()
        {
            ILEmitter    emitter    = new ILEmitter();
            ILCodeStream codeStream = emitter.NewCodeStream();

            ModuleDesc developerExperience = Context.ResolveAssembly(new AssemblyName("System.Private.DeveloperExperience.Console"), false);

            if (developerExperience != null)
            {
                TypeDesc   connectorType    = developerExperience.GetKnownType("Internal.DeveloperExperience", "DeveloperExperienceConnectorConsole");
                MethodDesc initializeMethod = connectorType.GetKnownMethod("Initialize", null);
                codeStream.Emit(ILOpcode.call, emitter.NewToken(initializeMethod));
            }

            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));
            }

            // 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.Emit(ILOpcode.call, emitter.NewToken(_mainMethod));
            if (_mainMethod.Signature.ReturnType.IsVoid)
            {
                codeStream.EmitLdc(0);
            }

            codeStream.Emit(ILOpcode.ret);

            return(emitter.Link(this));
        }
Beispiel #3
0
        public override MethodIL EmitIL()
        {
            ILEmitter    emitter    = new ILEmitter();
            ILCodeStream codeStream = emitter.NewCodeStream();

            ModuleDesc developerExperience = Context.ResolveAssembly(new AssemblyName("System.Private.DeveloperExperience.Console"), false);

            if (developerExperience != null)
            {
                TypeDesc   connectorType    = developerExperience.GetKnownType("Internal.DeveloperExperience", "DeveloperExperienceConnectorConsole");
                MethodDesc initializeMethod = connectorType.GetKnownMethod("Initialize", null);
                codeStream.Emit(ILOpcode.call, emitter.NewToken(initializeMethod));
            }

            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));
            }

            // 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.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));
        }