Exemplo n.º 1
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.EnqueueFieldsInitializer, allowParallel: true);
            }

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

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

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

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

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

            //
            return(diagnostics.AsEnumerable());
        }
Exemplo n.º 2
0
        public static void CompileSources(
            PhpCompilation compilation,
            PEModuleBuilder moduleBuilder,
            bool emittingPdb,
            bool hasDeclarationErrors,
            DiagnosticBag diagnostics,
            CancellationToken cancellationToken)
        {
            Debug.Assert(moduleBuilder != null);

            compilation.TrackMetric("sourceFilesCount", compilation.SourceSymbolCollection.FilesCount);

            using (compilation.StartMetric("diagnostics"))
            {
                // ensure flow analysis and collect diagnostics
                var declarationDiagnostics = compilation.GetDeclarationDiagnostics(cancellationToken);
                diagnostics.AddRange(declarationDiagnostics);

                // cancel the operation if there are errors
                if (hasDeclarationErrors |= declarationDiagnostics.HasAnyErrors() || cancellationToken.IsCancellationRequested)
                {
                    return;
                }
            }

            //
            var compiler = new SourceCompiler(compilation, moduleBuilder, emittingPdb, diagnostics, cancellationToken);

            using (compilation.StartMetric("emit"))
            {
                // Emit method bodies
                //   a. declared routines
                //   b. synthesized symbols
                compiler.EmitMethodBodies();
                compiler.EmitSynthesized();
                compiler.CompileReflectionEnumerators();

                // Entry Point (.exe)
                compiler.CompileEntryPoint();
            }
        }
Exemplo n.º 3
0
        public static IEnumerable <Diagnostic> BindAndAnalyze(PhpCompilation compilation)
        {
            var manager = compilation.GetBoundReferenceManager();   // ensure the references are resolved! (binds ReferenceManager)

            var diagnostics = new DiagnosticBag();
            var compiler    = new SourceCompiler(compilation, null, true, diagnostics, CancellationToken.None);

            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.EnqueueFieldsInitializer, allowParallel: true);
            }

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

            // TODO: Enable when the rewriting mechanism is refactored
            //if (!diagnostics.HasAnyErrors() && compilation.Options.OptimizationLevel == OptimizationLevel.Release)
            //{
            //    using (compilation.StartMetric("transform"))
            //    {
            //        // 3. Transform Semantic Trees for Runtime Optimization
            //        compiler.TransformMethods();
            //    }
            //}

            //
            return(diagnostics.AsEnumerable());
        }
Exemplo n.º 4
0
        bool RewriteMethods()
        {
            using (_compilation.StartMetric("transform"))
            {
                if (TransformMethods(ConcurrentBuild))
                {
                    WalkMethods(m =>
                    {
                        m.ControlFlowGraph?.FlowContext?.InvalidateAnalysis();
                        EnqueueRoutine(m);
                    },
                                allowParallel: true);
                }
                else
                {
                    // No changes performed => no need to repeat the analysis
                    return(false);
                }
            }

            //
            return(true);
        }