示例#1
0
            public void Analyze(GlobalCode /*!*/ ast, Analyzer /*!*/ analyzer)
            {
                analyzer.LeaveUnreachableCode();

                ExInfoFromParent info = new ExInfoFromParent(ast);

                // analyze auto-prepended inclusion (no code reachability checks):
                if (PrependedInclusion != null)
                {
                    info.Access = AccessType.None;
                    PrependedInclusion.Analyze(analyzer, info);
                }

                for (int i = 0; i < ast.Statements.Length; i++) // NOTE: ast.Statements may change during analysis, iterate in this way!
                {
                    if (analyzer.IsThisCodeUnreachable() && ast.Statements[i].IsDeclaration)
                    {
                        //unreachable declarations in global code are valid
                        analyzer.LeaveUnreachableCode();
                        ast.Statements[i] = ast.Statements[i].Analyze(analyzer);
                        analyzer.EnterUnreachableCode();
                    }
                    else
                    {
                        ast.Statements[i] = ast.Statements[i].Analyze(analyzer);
                    }
                }

                if (!ast.SourceUnit.IsPure)
                {
                    Analyzer.ValidateLabels(analyzer.ErrorSink, ast.SourceUnit, labels);
                }

                // analyze auto-prepended inclusion (no code reachability checks):
                if (AppendedInclusion != null)
                {
                    info.Access = AccessType.Read;
                    AppendedInclusion.Analyze(analyzer, info);
                }

                analyzer.LeaveUnreachableCode();
            }
示例#2
0
            /// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
            /// <param name="ast">Instance.</param>
            public void Emit(GlobalCode /*!*/ ast, CodeGenerator /*!*/ codeGenerator)
            {
                // TODO: improve
                codeGenerator.EnterGlobalCodeDeclaration(this.varTable, labels, (CompilationSourceUnit)ast.SourceUnit);

                //
                if (codeGenerator.CompilationUnit.IsTransient)
                {
                    codeGenerator.DefineLabels(labels);

                    codeGenerator.ChainBuilder.Create();

                    foreach (Statement statement in ast.Statements)
                    {
                        statement.Emit(codeGenerator);
                    }

                    codeGenerator.ChainBuilder.End();

                    // return + appended file emission:
                    codeGenerator.EmitRoutineEpilogue(ast, true);
                }
#if !SILVERLIGHT
                else if (codeGenerator.CompilationUnit.IsPure)
                {
                    codeGenerator.ChainBuilder.Create();

                    foreach (Statement statement in ast.Statements)
                    {
                        // skip empty statements in global code (they emit sequence points, which is undesirable):
                        if (!(statement is EmptyStmt))
                        {
                            statement.Emit(codeGenerator);
                        }
                    }

                    codeGenerator.ChainBuilder.End();
                }
                else
                {
                    ScriptCompilationUnit unit = (ScriptCompilationUnit)codeGenerator.CompilationUnit;

                    ILEmitter il = codeGenerator.IL;

                    if (codeGenerator.Context.Config.Compiler.Debug)
                    {
                        codeGenerator.MarkSequencePoint(0);
                        il.Emit(OpCodes.Nop);
                    }

                    codeGenerator.DefineLabels(labels);

                    // CALL <self>.<Declare>(context);
                    codeGenerator.EmitLoadScriptContext();
                    il.Emit(OpCodes.Call, unit.ScriptBuilder.DeclareHelperBuilder);

                    // IF (<is main script>) CALL <prepended script>.Main()
                    if (PrependedInclusion != null)
                    {
                        PrependedInclusion.Emit(codeGenerator);
                    }

                    codeGenerator.ChainBuilder.Create();

                    foreach (Statement statement in ast.Statements)
                    {
                        statement.Emit(codeGenerator);
                    }

                    codeGenerator.ChainBuilder.End();

                    // return + appended file emission:
                    codeGenerator.EmitRoutineEpilogue(ast, false);
                }
#endif
                codeGenerator.LeaveGlobalCodeDeclaration();
            }