예제 #1
0
		/// <include file='Doc/Nodes.xml' path='doc/method[@name="Emit"]/*'/>
		internal void Emit(CodeGenerator/*!*/ codeGenerator)
		{
			// TODO: improve
			codeGenerator.EnterGlobalCodeDeclaration(this.varTable, labels, sourceUnit);

            // custom body prolog emittion:
            PluginHandler.EmitBeforeBody(codeGenerator.IL, statements);

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

				codeGenerator.ChainBuilder.Create();

				foreach (Statement statement in statements)
					statement.Emit(codeGenerator);

				codeGenerator.ChainBuilder.End();

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

				foreach (Statement statement in 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(1, 1, 1, 2);
                    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 statements)
					statement.Emit(codeGenerator);

				codeGenerator.ChainBuilder.End();

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