Inheritance: Compilation
示例#1
0
        private SourceCompiler(PhpCompilation compilation, PEModuleBuilder moduleBuilder, bool emittingPdb, DiagnosticBag diagnostics)
        {
            Contract.ThrowIfNull(compilation);
            Contract.ThrowIfNull(moduleBuilder);
            Contract.ThrowIfNull(diagnostics);

            _compilation = compilation;
            _moduleBuilder = moduleBuilder;
            _emittingPdb = emittingPdb;
            _diagnostics = diagnostics;

            // parallel worklist algorithm
            _worklist = new Worklist<BoundBlock>(AnalyzeBlock);

            // semantic model
        }
示例#2
0
            internal void CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                    return;

                // TODO: lock

                Debug.Assert(_lazyExplicitReferences.IsDefault);
                Debug.Assert(_lazyCorLibrary == null);
                Debug.Assert(_lazyPhpCorLibrary == null);

                //
                var externalRefs = CorLibReferences.SelectMany(reference => compilation.Options.MetadataReferenceResolver.ResolveReference(reference, null, new MetadataReferenceProperties()))
                    .Concat(compilation.ExternalReferences).AsImmutable();
                var assemblies = new List<AssemblySymbol>(externalRefs.Length);

                var referencesMap = new Dictionary<MetadataReference, IAssemblySymbol>();
                var metadataMap = new Dictionary<IAssemblySymbol, MetadataReference>();
                var assembliesMap = new Dictionary<AssemblyIdentity, PEAssemblySymbol>();

                var refmodules = new List<PEModuleSymbol>();
                
                foreach (PortableExecutableReference pe in externalRefs)
                {
                    var symbol = PEAssemblySymbol.Create(pe);
                    if (symbol != null)
                    {
                        assemblies.Add(symbol);
                        referencesMap[pe] = symbol;
                        metadataMap[symbol] = pe;

                        if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                            _lazyCorLibrary = symbol;

                        if (_lazyPhpCorLibrary == null && symbol.IsPchpCorLibrary)
                            _lazyPhpCorLibrary = symbol;

                        // cache bound assembly symbol
                        _assembliesMap.Add(symbol.Identity, symbol);

                        // list of modules to initialize later
                        refmodules.AddRange(symbol.Modules.Cast<PEModuleSymbol>());
                    }
                    else
                    {
                        throw new Exception($"symbol '{pe.FilePath}' could not be created!");
                    }
                }

                //
                _lazyExplicitReferences = externalRefs;
                _lazyImplicitReferences = ImmutableArray<MetadataReference>.Empty;
                _metadataMap = metadataMap.ToImmutableDictionary();
                _referencesMap = referencesMap.ToImmutableDictionary();

                //
                var assembly = new SourceAssemblySymbol(compilation, compilation.Options.ModuleName, compilation.Options.ModuleName);
                assembly.SetCorLibrary(_lazyCorLibrary);
                compilation._lazyAssemblySymbol = assembly;

                assembly.SourceModule.SetReferences(new ModuleReferences<AssemblySymbol>(
                    assemblies.Select(x => x.Identity).AsImmutable(),
                    assemblies.AsImmutable(),
                    ImmutableArray<UnifiedAssembly<AssemblySymbol>>.Empty), assembly);

                assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                // recursively initialize references of referenced modules
                SetReferencesOfReferencedModules(compilation.Options.MetadataReferenceResolver, refmodules);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null) throw new DllNotFoundException("Peachpie.Runtime not found");
                if (_lazyCorLibrary == null) throw new DllNotFoundException("A corlib not found");
                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);
            }
示例#3
0
 public WellKnownMembersSignatureComparer(PhpCompilation compilation)
 {
     _compilation = compilation;
 }
示例#4
0
        ///// <summary>
        ///// <see cref="CharSet"/> effective for this symbol (type or DllImport method).
        ///// Nothing if <see cref="DefaultCharSetAttribute"/> isn't applied on the containing module or it doesn't apply on this symbol.
        ///// </summary>
        ///// <remarks>
        ///// Determined based upon value specified via <see cref="DefaultCharSetAttribute"/> applied on the containing module.
        ///// </remarks>
        //internal CharSet? GetEffectiveDefaultMarshallingCharSet()
        //{
        //    Debug.Assert(this.Kind == SymbolKind.NamedType || this.Kind == SymbolKind.Method);
        //    return this.ContainingModule.DefaultMarshallingCharSet;
        //}

        internal bool IsFromCompilation(PhpCompilation compilation)
        {
            Debug.Assert(compilation != null);
            return(compilation == this.DeclaringCompilation);
        }
            internal SourceAssemblySymbol CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return(compilation._lazyAssemblySymbol);
                }

                var resolver   = compilation.Options.MetadataReferenceResolver;
                var moduleName = compilation.MakeSourceModuleName();

                var assemblies = new List <AssemblySymbol>();

                if (_lazyExplicitReferences.IsDefault)
                {
                    //
                    var externalRefs  = compilation.ExternalReferences;
                    var referencesMap = new Dictionary <MetadataReference, IAssemblySymbol>();
                    var metadataMap   = new Dictionary <IAssemblySymbol, MetadataReference>();
                    var assembliesMap = new Dictionary <AssemblyIdentity, PEAssemblySymbol>();
                    var observed      = new HashSet <AssemblyIdentity>();

                    foreach (PortableExecutableReference pe in externalRefs)
                    {
                        var peass = ((AssemblyMetadata)pe.GetMetadata()).GetAssembly();

                        if (!observed.Add(peass.Identity))
                        {
                            // already added reference identity, different metadata
                            referencesMap[pe] = _observedMetadata[peass.Identity];
                            Debug.Assert(referencesMap[pe] != null);
                            continue;
                        }

                        var symbol = _observedMetadata.TryGetOrDefault(peass.Identity) ?? PEAssemblySymbol.Create(pe, peass, isLinked: true);
                        if (symbol != null)
                        {
                            assemblies.Add(symbol);
                            referencesMap[pe]   = symbol;
                            metadataMap[symbol] = pe;

                            if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                            {
                                _lazyCorLibrary = symbol;
                            }

                            if (_lazyPhpCorLibrary == null && symbol.IsPchpCorLibrary)
                            {
                                _lazyPhpCorLibrary = symbol;
                            }

                            // cache bound assembly symbol
                            _observedMetadata[symbol.Identity] = symbol;
                        }
                        else
                        {
                            _diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, peass.Identity);
                        }
                    }

                    // list of modules to initialize later
                    var refmodules = assemblies.SelectMany(symbol => symbol.Modules.Cast <PEModuleSymbol>()).ToList();

                    //
                    _lazyExplicitReferences = externalRefs;
                    _lazyImplicitReferences = ImmutableArray <MetadataReference> .Empty;
                    _metadataMap            = metadataMap.ToImmutableDictionary();
                    _referencesMap          = referencesMap.ToImmutableDictionary();

                    //
                    assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                    // recursively initialize references of referenced modules
                    SetReferencesOfReferencedModules(resolver, refmodules);
                }
                else
                {
                    foreach (PortableExecutableReference pe in _lazyExplicitReferences)
                    {
                        var ass = (AssemblySymbol)_referencesMap[pe];
                        Debug.Assert(ass != null);
                        assemblies.Add(ass);
                    }
                }

                //
                var assembly = new SourceAssemblySymbol(compilation, this.SimpleAssemblyName, moduleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                assembly.SourceModule.SetReferences(new ModuleReferences <AssemblySymbol>(
                                                        assemblies.Select(x => x.Identity).AsImmutable(),
                                                        assemblies.AsImmutable(),
                                                        ImmutableArray <UnifiedAssembly <AssemblySymbol> > .Empty), assembly);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    _diagnostics.Add(Location.None, Errors.ErrorCode.ERR_MetadataFileNotFound, "Peachpie.Runtime.dll");
                    throw new DllNotFoundException("Peachpie.Runtime not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("A corlib not found");
                }

                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);

                //
                return(assembly);
            }
示例#6
0
            internal void CreateSourceAssemblyForCompilation(PhpCompilation compilation)
            {
                if (compilation._lazyAssemblySymbol != null)
                {
                    return;
                }

                // TODO: lock

                Debug.Assert(_lazyExplicitReferences.IsDefault);
                Debug.Assert(_lazyCorLibrary == null);
                Debug.Assert(_lazyPhpCorLibrary == null);

                //
                var externalRefs = CorLibReferences.SelectMany(reference => compilation.Options.MetadataReferenceResolver.ResolveReference(reference, null, new MetadataReferenceProperties()))
                                   .Concat(compilation.ExternalReferences).AsImmutable();
                var assemblies = new List <AssemblySymbol>(externalRefs.Length);

                var referencesMap = new Dictionary <MetadataReference, IAssemblySymbol>();
                var metadataMap   = new Dictionary <IAssemblySymbol, MetadataReference>();
                var assembliesMap = new Dictionary <AssemblyIdentity, PEAssemblySymbol>();

                var refmodules = new List <PEModuleSymbol>();

                foreach (PortableExecutableReference pe in externalRefs)
                {
                    var symbol = PEAssemblySymbol.Create(pe);
                    if (symbol != null)
                    {
                        assemblies.Add(symbol);
                        referencesMap[pe]   = symbol;
                        metadataMap[symbol] = pe;

                        if (_lazyCorLibrary == null && symbol.IsCorLibrary)
                        {
                            _lazyCorLibrary = symbol;
                        }

                        if (_lazyPhpCorLibrary == null && symbol.IsPchpCorLibrary)
                        {
                            _lazyPhpCorLibrary = symbol;
                        }

                        // cache bound assembly symbol
                        _assembliesMap.Add(symbol.Identity, symbol);

                        // list of modules to initialize later
                        refmodules.AddRange(symbol.Modules.Cast <PEModuleSymbol>());
                    }
                    else
                    {
                        throw new Exception($"symbol '{pe.FilePath}' could not be created!");
                    }
                }

                //
                _lazyExplicitReferences = externalRefs;
                _lazyImplicitReferences = ImmutableArray <MetadataReference> .Empty;
                _metadataMap            = metadataMap.ToImmutableDictionary();
                _referencesMap          = referencesMap.ToImmutableDictionary();

                //
                var assembly = new SourceAssemblySymbol(compilation, compilation.Options.ModuleName, compilation.Options.ModuleName);

                assembly.SetCorLibrary(_lazyCorLibrary);
                compilation._lazyAssemblySymbol = assembly;

                assembly.SourceModule.SetReferences(new ModuleReferences <AssemblySymbol>(
                                                        assemblies.Select(x => x.Identity).AsImmutable(),
                                                        assemblies.AsImmutable(),
                                                        ImmutableArray <UnifiedAssembly <AssemblySymbol> > .Empty), assembly);

                assemblies.ForEach(ass => ass.SetCorLibrary(_lazyCorLibrary));

                // recursively initialize references of referenced modules
                SetReferencesOfReferencedModules(compilation.Options.MetadataReferenceResolver, refmodules);

                // set cor types for this compilation
                if (_lazyPhpCorLibrary == null)
                {
                    throw new DllNotFoundException("Peachpie.Runtime not found");
                }
                if (_lazyCorLibrary == null)
                {
                    throw new DllNotFoundException("A corlib not found");
                }
                compilation.CoreTypes.Update(_lazyPhpCorLibrary);
                compilation.CoreTypes.Update(_lazyCorLibrary);
            }
示例#7
0
        internal static PhpCompilation Create(
            string assemblyName,
            IEnumerable<SourceUnit> syntaxTrees = null,
            IEnumerable<MetadataReference> references = null,
            PhpCompilationOptions options = null)
        {
            Debug.Assert(options != null);
            CheckAssemblyName(assemblyName);

            var compilation = new PhpCompilation(
                assemblyName,
                options,
                ValidateReferences<CompilationReference>(references));

            //
            compilation._tables.PopulateTables(compilation, syntaxTrees);

            //
            return compilation;
        }
示例#8
0
        public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation, CancellationToken cancellationToken)
        {
            var manager = compilation.GetBoundReferenceManager();   // ensure the references are resolved! (binds ReferenceManager)

            var diagnostics = new DiagnosticBag();
            var compiler    = new SourceCompiler(compilation, null, true, diagnostics, cancellationToken);

            using (compilation.StartMetric("bind"))
            {
                // 1. Bind Syntax & Symbols to Operations (CFG)
                //   a. construct CFG, bind AST to Operation
                //   b. declare table of local variables
                compiler.WalkMethods(compiler.EnqueueRoutine, allowParallel: true);
                compiler.WalkTypes(compiler.EnqueueType, allowParallel: true);
            }

            // Repeat analysis and transformation until either the limit is met or there are no more changes
            int transformation = 0;

            do
            {
                using (compilation.StartMetric("analysis"))
                {
                    // 2. Analyze Operations
                    //   a. type analysis (converge type - mask), resolve symbols
                    //   b. lower semantics, update bound tree, repeat
                    compiler.AnalyzeMethods();
                }

                using (compilation.StartMetric("bind types"))
                {
                    // 3. Resolve operators and types
                    compiler.BindTypes();
                }

                using (compilation.StartMetric(nameof(ForwardLateStaticBindings)))
                {
                    // 4. forward the late static type if needed
                    compiler.ForwardLateStaticBindings();
                }

                // 5. Transform Semantic Trees for Runtime Optimization
            } while (
                transformation++ < compiler.MaxTransformCount && // limit number of lowering cycles
                !cancellationToken.IsCancellationRequested &&    // user canceled ?
                compiler.RewriteMethods());                      // try lower the semantics

            // Track the number of actually performed transformations
            compilation.TrackMetric("transformations", transformation - 1);

            using (compilation.StartMetric("diagnostic"))
            {
                // 6. Collect diagnostics
                compiler.DiagnoseMethods();
                compiler.DiagnoseTypes();
                compiler.DiagnoseFiles();
            }

            //
            return(diagnostics.AsEnumerable());
        }
示例#9
0
        public static void CompileSources(
            PhpCompilation compilation,
            PEModuleBuilder moduleBuilder,
            bool emittingPdb,
            bool hasDeclarationErrors,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics);

            // 1.Bind Syntax & Symbols to Operations (CFG)
            //   a.equivalent to building CFG
            //   b.most generic types(and empty type - mask)
            compiler.WalkMethods(compiler.EnqueueRoutine);
            compiler.WalkTypes(compiler.EnqueueFieldsInitializer);

            // 2.Analyze Operations
            //   a.declared variables
            //   b.build global variables/constants table
            //   c.type analysis(converge type - mask), resolve symbols
            //   d.lower semantics, update bound tree, repeat
            compiler.AnalyzeMethods();

            // 3. Emit method bodies
            //   a. declared routines
            //   b. synthesized symbols
            compiler.EmitMethodBodies();
            compiler.EmitSynthesized();
            compiler.CompileReflectionEnumerators(cancellationToken);

            // 4. Entry Point (.exe)
            compiler.CompileEntryPoint(cancellationToken);
        }