⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codegen.cs

📁 C#编译器源代码。Micorsoft开放源代码
💻 CS
📖 第 1 页 / 共 3 页
字号:
//// codegen.cs: The code generator//// Author://   Miguel de Icaza (miguel@ximian.com)//// (C) 2001, 2002, 2003 Ximian, Inc.// (C) 2004 Novell, Inc.//#if !DEBUG	#define PRODUCTION#endifusing System;using System.IO;using System.Collections;using System.Collections.Specialized;using System.Reflection;using System.Reflection.Emit;using System.Runtime.InteropServices;using System.Security;using System.Security.Cryptography;using System.Security.Permissions;using Mono.Security.Cryptography;namespace Mono.CSharp {	/// <summary>	///    Code generator class.	/// </summary>	public class CodeGen {		static AppDomain current_domain;		static public SymbolWriter SymbolWriter;		public static AssemblyClass Assembly;		public static ModuleClass Module;		static CodeGen ()		{			Reset ();		}		public static void Reset ()		{			Assembly = new AssemblyClass ();			Module = new ModuleClass (RootContext.Unsafe);		}		public static string Basename (string name)		{			int pos = name.LastIndexOf ('/');			if (pos != -1)				return name.Substring (pos + 1);			pos = name.LastIndexOf ('\\');			if (pos != -1)				return name.Substring (pos + 1);			return name;		}		public static string Dirname (string name)		{			int pos = name.LastIndexOf ('/');			if (pos != -1)				return name.Substring (0, pos);			pos = name.LastIndexOf ('\\');			if (pos != -1)				return name.Substring (0, pos);			return ".";		}		static public string FileName;		//		// Initializes the symbol writer		//		static void InitializeSymbolWriter (string filename)		{			SymbolWriter = SymbolWriter.GetSymbolWriter (Module.Builder, filename);			//			// If we got an ISymbolWriter instance, initialize it.			//			if (SymbolWriter == null) {				Report.Warning (					-18, "Could not find the symbol writer assembly (Mono.CompilerServices.SymbolWriter.dll). This is normally an installation problem. Please make sure to compile and install the mcs/class/Mono.CompilerServices.SymbolWriter directory.");				return;			}		}		//		// Initializes the code generator variables		//		static public bool Init (string name, string output, bool want_debugging_support)		{			FileName = output;			AssemblyName an = Assembly.GetAssemblyName (name, output);			if (an == null)				return false;			if (an.KeyPair != null) {				// If we are going to strong name our assembly make				// sure all its refs are strong named				foreach (Assembly a in RootNamespace.Global.Assemblies) {					AssemblyName ref_name = a.GetName ();					byte [] b = ref_name.GetPublicKeyToken ();					if (b == null || b.Length == 0) {						Report.Warning (1577, "Assembly generation failed " +								"-- Referenced assembly '" +								ref_name.Name +								"' does not have a strong name.");						//Environment.Exit (1);					}				}			}						current_domain = AppDomain.CurrentDomain;			try {				Assembly.Builder = current_domain.DefineDynamicAssembly (an,					AssemblyBuilderAccess.Save, Dirname (name));			}			catch (ArgumentException) {				// specified key may not be exportable outside it's container				if (RootContext.StrongNameKeyContainer != null) {					Report.Error (1548, "Could not access the key inside the container `" +						RootContext.StrongNameKeyContainer + "'.");					Environment.Exit (1);				}				return false;			}			catch (CryptographicException) {				if ((RootContext.StrongNameKeyContainer != null) || (RootContext.StrongNameKeyFile != null)) {					Report.Error (1548, "Could not use the specified key to strongname the assembly.");					Environment.Exit (1);				}				return false;			}			//			// Pass a path-less name to DefineDynamicModule.  Wonder how			// this copes with output in different directories then.			// FIXME: figure out how this copes with --output /tmp/blah			//			// If the third argument is true, the ModuleBuilder will dynamically			// load the default symbol writer.			//			Module.Builder = Assembly.Builder.DefineDynamicModule (				Basename (name), Basename (output), false);			if (want_debugging_support)				InitializeSymbolWriter (output);			return true;		}		static public void Save (string name)		{			try {				Assembly.Builder.Save (Basename (name));			}			catch (COMException) {				if ((RootContext.StrongNameKeyFile == null) || (!RootContext.StrongNameDelaySign))					throw;				// FIXME: it seems Microsoft AssemblyBuilder doesn't like to delay sign assemblies 				Report.Error (1548, "Couldn't delay-sign the assembly with the '" +					RootContext.StrongNameKeyFile +					"', Use MCS with the Mono runtime or CSC to compile this assembly.");			}			catch (System.IO.IOException io) {				Report.Error (16, "Could not write to file `"+name+"', cause: " + io.Message);			}			catch (System.UnauthorizedAccessException ua) {				Report.Error (16, "Could not write to file `"+name+"', cause: " + ua.Message);			}			if (SymbolWriter != null)				SymbolWriter.WriteSymbolFile ();		}	}	/// <summary>	///   An Emit Context is created for each body of code (from methods,	///   properties bodies, indexer bodies or constructor bodies)	/// </summary>	public class EmitContext {		public readonly DeclSpace DeclSpace;		public DeclSpace TypeContainer;		public ILGenerator   ig;		/// <summary>		///   This variable tracks the `checked' state of the compilation,		///   it controls whether we should generate code that does overflow		///   checking, or if we generate code that ignores overflows.		///		///   The default setting comes from the command line option to generate		///   checked or unchecked code plus any source code changes using the		///   checked/unchecked statements or expressions.   Contrast this with		///   the ConstantCheckState flag.		/// </summary>				public bool CheckState;		/// <summary>		///   The constant check state is always set to `true' and cant be changed		///   from the command line.  The source code can change this setting with		///   the `checked' and `unchecked' statements and expressions. 		/// </summary>		public bool ConstantCheckState;		/// <summary>		///   Whether we are emitting code inside a static or instance method		/// </summary>		public bool IsStatic;		/// <summary>		///   Whether the actual created method is static or instance method.		///   Althoug the method might be declared as `static', if an anonymous		///   method is involved, we might turn this into an instance method.		///		///   So this reflects the low-level staticness of the method, while		///   IsStatic represents the semantic, high-level staticness.		/// </summary>		public bool MethodIsStatic;		/// <summary>		///   Whether we are emitting a field initializer		/// </summary>		public bool IsFieldInitializer;		/// <summary>		///   The value that is allowed to be returned or NULL if there is no		///   return type.		/// </summary>		public Type ReturnType;		/// <summary>		///   Points to the Type (extracted from the TypeContainer) that		///   declares this body of code		/// </summary>		public Type ContainerType;				/// <summary>		///   Whether this is generating code for a constructor		/// </summary>		public bool IsConstructor;		/// <summary>		///   Whether we're control flow analysis enabled		/// </summary>		public bool DoFlowAnalysis;		/// <summary>		///   Whether we're control flow analysis disabled on struct		/// </summary>		public bool OmitStructFlowAnalysis;		/// <summary>		///   Keeps track of the Type to LocalBuilder temporary storage created		///   to store structures (used to compute the address of the structure		///   value on structure method invocations)		/// </summary>		public Hashtable temporary_storage;		public Block CurrentBlock;		public int CurrentFile;		/// <summary>		///   The location where we store the return value.		/// </summary>		LocalBuilder return_value;		/// <summary>		///   The location where return has to jump to return the		///   value		/// </summary>		public Label ReturnLabel;		/// <summary>		///   If we already defined the ReturnLabel		/// </summary>		public bool HasReturnLabel;		/// <summary>		///   Whether we are inside an iterator block.		/// </summary>		public bool InIterator;		public bool IsLastStatement;		/// <summary>		///  Whether we are inside an unsafe block		/// </summary>		public bool InUnsafe;		/// <summary>		///  Whether we are in a `fixed' initialization		/// </summary>		public bool InFixedInitializer;		public bool InRefOutArgumentResolving;		public bool InCatch;		public bool InFinally;		/// <summary>		///  Whether we are inside an anonymous method.		/// </summary>		public AnonymousContainer CurrentAnonymousMethod;				/// <summary>		///   Location for this EmitContext		/// </summary>		public Location loc;		/// <summary>		///   Inside an enum definition, we do not resolve enumeration values		///   to their enumerations, but rather to the underlying type/value		///   This is so EnumVal + EnumValB can be evaluated.		///		///   There is no "E operator + (E x, E y)", so during an enum evaluation		///   we relax the rules		/// </summary>		public bool InEnumContext;		/// <summary>		///   Anonymous methods can capture local variables and fields,		///   this object tracks it.  It is copied from the TopLevelBlock		///   field.		/// </summary>		public CaptureContext capture_context;		/// <summary>		/// Trace when method is called and is obsolete then this member suppress message		/// when call is inside next [Obsolete] method or type.		/// </summary>		public bool TestObsoleteMethodUsage = true;		/// <summary>		///    The current iterator		/// </summary>		public Iterator CurrentIterator;		/// <summary>		///    Whether we are in the resolving stage or not		/// </summary>		enum Phase {			Created,			Resolving,			Emitting		}				Phase current_phase;		FlowBranching current_flow_branching;		static int next_id = 0;		int id = ++next_id;		public override string ToString ()		{			return String.Format ("EmitContext ({0}:{1}:{2})", id,					      CurrentIterator, capture_context, loc);		}				public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig,				    Type return_type, int code_flags, bool is_constructor)		{			this.ig = ig;			TypeContainer = parent;			DeclSpace = ds;			CheckState = RootContext.Checked;			ConstantCheckState = true;			IsStatic = (code_flags & Modifiers.STATIC) != 0;			MethodIsStatic = IsStatic;			InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0;			ReturnType = return_type;			IsConstructor = is_constructor;			CurrentBlock = null;			CurrentFile = 0;			current_phase = Phase.Created;						if (parent != null){				// Can only be null for the ResolveType contexts.				ContainerType = parent.TypeBuilder;				if (parent.UnsafeContext)					InUnsafe = true;				else					InUnsafe = (code_flags & Modifiers.UNSAFE) != 0;			}			loc = l;			if (ReturnType == TypeManager.void_type)				ReturnType = null;		}		public EmitContext (TypeContainer tc, Location l, ILGenerator ig,				    Type return_type, int code_flags, bool is_constructor)			: this (tc, tc, l, ig, return_type, code_flags, is_constructor)		{		}		public EmitContext (TypeContainer tc, Location l, ILGenerator ig,				    Type return_type, int code_flags)			: this (tc, tc, l, ig, return_type, code_flags, false)		{		}		public FlowBranching CurrentBranching {			get {				return current_flow_branching;			}		}		public bool HaveCaptureInfo {			get {				return capture_context != null;			}		}		// <summary>		//   Starts a new code branching.  This inherits the state of all local		//   variables and parameters from the current branching.		// </summary>		public FlowBranching StartFlowBranching (FlowBranching.BranchingType type, Location loc)		{			current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, null, loc);			return current_flow_branching;		}		// <summary>		//   Starts a new code branching for block `block'.		// </summary>		public FlowBranching StartFlowBranching (Block block)		{			FlowBranching.BranchingType type;			if ((CurrentBranching != null) &&			    (CurrentBranching.Type == FlowBranching.BranchingType.Switch))				type = FlowBranching.BranchingType.SwitchSection;			else				type = FlowBranching.BranchingType.Block;			DoFlowAnalysis = true;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -