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 }
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); }
public WellKnownMembersSignatureComparer(PhpCompilation compilation) { _compilation = compilation; }
///// <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); }
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); }
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; }
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()); }
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); }