예제 #1
0
        /// <summary>
        /// Builds a delegate that will execute just this scripts code.
        /// </summary>
        private Func <object[], Task <T> > Build <T>(
            Compilation compilation,
            DiagnosticBag diagnostics,
            bool emitDebugInformation,
            CancellationToken cancellationToken)
        {
            var entryPoint = compilation.GetEntryPoint(cancellationToken);

            using (var peStream = new MemoryStream())
                using (var pdbStreamOpt = emitDebugInformation ? new MemoryStream() : null)
                {
                    var emitOptions = EmitOptions.Default;

                    if (emitDebugInformation)
                    {
                        emitOptions = emitOptions.WithDebugInformationFormat(PdbHelpers.GetPlatformSpecificDebugInformationFormat());
                    }

                    var emitResult = compilation.Emit(
                        peStream: peStream,
                        pdbStream: pdbStreamOpt,
                        xmlDocumentationStream: null,
                        win32Resources: null,
                        manifestResources: null,
                        options: emitOptions,
                        cancellationToken: cancellationToken);

                    diagnostics.AddRange(emitResult.Diagnostics);

                    if (!emitResult.Success)
                    {
                        return(null);
                    }

                    // let the loader know where to find assemblies:
                    foreach (var referencedAssembly in compilation.GetBoundReferenceManager().GetReferencedAssemblies())
                    {
                        var path = (referencedAssembly.Key as PortableExecutableReference)?.FilePath;
                        if (path != null)
                        {
                            // TODO: Should the #r resolver return contract metadata and runtime assembly path -
                            // Contract assembly used in the compiler, RT assembly path here.
                            _assemblyLoader.RegisterDependency(referencedAssembly.Value.Identity, path);
                        }
                    }

                    peStream.Position = 0;

                    if (pdbStreamOpt != null)
                    {
                        pdbStreamOpt.Position = 0;
                    }

                    var assembly          = _assemblyLoader.LoadAssemblyFromStream(peStream, pdbStreamOpt);
                    var runtimeEntryPoint = GetEntryPointRuntimeMethod(entryPoint, assembly, cancellationToken);

                    return(runtimeEntryPoint.CreateDelegate <Func <object[], Task <T> > >());
                }
        }
예제 #2
0
        /// <summary>
        /// Builds a delegate that will execute just this scripts code.
        /// </summary>
        public Func <object[], object> Build(
            Script script,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            var compilation = script.GetCompilation();

            using (var peStream = new MemoryStream())
            {
                var emitResult = compilation.Emit(
                    peStream: peStream,
                    pdbStream: null,
                    xmlDocumentationStream: null,
                    win32Resources: null,
                    manifestResources: null,
                    options: EmitOptions.Default,
                    cancellationToken: cancellationToken);

                diagnostics.AddRange(emitResult.Diagnostics);

                if (!emitResult.Success)
                {
                    return(null);
                }

                // let the loader know where to find assemblies:
                foreach (var referencedAssembly in compilation.GetBoundReferenceManager().GetReferencedAssemblies())
                {
                    var path = (referencedAssembly.Key as PortableExecutableReference)?.FilePath;
                    if (path != null)
                    {
                        // TODO: Should the #r resolver return contract metadata and runtime assembly path -
                        // Contract assembly used in the compiler, RT assembly path here.
                        _assemblyLoader.RegisterDependency(referencedAssembly.Value.Identity, path);
                    }
                }

                peStream.Position = 0;

                var assembly = _assemblyLoader.Load(peStream, pdbStream: null);

                // TODO: GetEntryPoint currently doesn't work for scripts/submissions.
                // See https://github.com/dotnet/roslyn/issues/3719.
                // var entryPoint = compilation.GetEntryPoint(cancellationToken);
                var entryPointMethod = GetEntryPointRuntimeMethod(emitResult.EntryPointOpt, assembly, cancellationToken);

                return(entryPointMethod.CreateDelegate <Func <object[], object> >());
            }
        }