EmitInt() public method

public EmitInt ( int i ) : void
i int
return void
示例#1
0
		public override void Emit (EmitContext ec)
		{
			int [] words = decimal.GetBits (Value);
			int power = (words [3] >> 16) & 0xff;

			if (power == 0) {
				if (Value <= int.MaxValue && Value >= int.MinValue) {
					if (TypeManager.void_decimal_ctor_int_arg == null) {
						TypeManager.void_decimal_ctor_int_arg = TypeManager.GetPredefinedConstructor (
							TypeManager.decimal_type, loc, TypeManager.int32_type);

						if (TypeManager.void_decimal_ctor_int_arg == null)
							return;
					}

					ec.EmitInt ((int) Value);
					ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
					return;
				}

				if (Value <= long.MaxValue && Value >= long.MinValue) {
					if (TypeManager.void_decimal_ctor_long_arg == null) {
						TypeManager.void_decimal_ctor_long_arg = TypeManager.GetPredefinedConstructor (
							TypeManager.decimal_type, loc, TypeManager.int64_type);

						if (TypeManager.void_decimal_ctor_long_arg == null)
							return;
					}

					ec.EmitLong ((long) Value);
					ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_long_arg);
					return;
				}
			}

			ec.EmitInt (words [0]);
			ec.EmitInt (words [1]);
			ec.EmitInt (words [2]);

			// sign
			ec.EmitInt (words [3] >> 31);

			// power
			ec.EmitInt (power);

			if (TypeManager.void_decimal_ctor_five_args == null) {
				TypeManager.void_decimal_ctor_five_args = TypeManager.GetPredefinedConstructor (
					TypeManager.decimal_type, loc, TypeManager.int32_type, TypeManager.int32_type,
					TypeManager.int32_type, TypeManager.bool_type, TypeManager.byte_type);

				if (TypeManager.void_decimal_ctor_five_args == null)
					return;
			}

			ec.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
		}
示例#2
0
文件: iterators.cs 项目: speier/shake
        void EmitMoveNext_NoResumePoints(EmitContext ec, Block original_block)
        {
            ec.Emit (OpCodes.Ldarg_0);
            ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);

            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt ((int) State.After);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            // We only care if the PC is zero (start executing) or non-zero (don't do anything)
            ec.Emit (OpCodes.Brtrue, move_next_error);

            SymbolWriter.StartIteratorBody (ec);
            original_block.Emit (ec);
            SymbolWriter.EndIteratorBody (ec);

            ec.MarkLabel (move_next_error);
            ec.Emit (OpCodes.Ldc_I4_0);
            ec.Emit (OpCodes.Ret);
        }
示例#3
0
文件: iterators.cs 项目: speier/shake
                protected override void DoEmit(EmitContext ec)
                {
                    Label label_init = ec.DefineLabel ();

                    ec.Emit (OpCodes.Ldarg_0);
                    ec.Emit (OpCodes.Ldflda, host.PC.Spec);
                    ec.EmitInt ((int) Iterator.State.Start);
                    ec.EmitInt ((int) Iterator.State.Uninitialized);
                    ec.Emit (OpCodes.Call, TypeManager.int_interlocked_compare_exchange);

                    ec.EmitInt ((int) Iterator.State.Uninitialized);
                    ec.Emit (OpCodes.Bne_Un_S, label_init);

                    ec.Emit (OpCodes.Ldarg_0);
                    ec.Emit (OpCodes.Ret);

                    ec.MarkLabel (label_init);

                    new_storey.Emit (ec);
                    ec.Emit (OpCodes.Ret);
                }
示例#4
0
        void EmitMoveNext(EmitContext ec)
        {
            move_next_ok    = ec.DefineLabel();
            move_next_error = ec.DefineLabel();

            if (resume_points == null)
            {
                EmitMoveNext_NoResumePoints(ec);
                return;
            }

            current_pc = ec.GetTemporaryLocal(ec.BuiltinTypes.UInt);
            ec.EmitThis();
            ec.Emit(OpCodes.Ldfld, storey.PC.Spec);
            ec.Emit(OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.PC.Spec);

            Label[] labels = new Label[1 + resume_points.Count];
            labels[0] = ec.DefineLabel();

            bool need_skip_finally = false;

            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = resume_points[i];
                need_skip_finally |= s is ExceptionStatement;
                labels[i + 1]      = s.PrepareForEmit(ec);
            }

            if (need_skip_finally)
            {
                skip_finally = ec.GetTemporaryLocal(ec.BuiltinTypes.Bool);
                ec.EmitInt(0);
                ec.Emit(OpCodes.Stloc, skip_finally);
            }

            var async_init = this as AsyncInitializer;

            if (async_init != null)
            {
                ec.BeginExceptionBlock();
            }

            ec.Emit(OpCodes.Ldloc, current_pc);
            ec.Emit(OpCodes.Switch, labels);

            ec.Emit(async_init != null ? OpCodes.Leave : OpCodes.Br, move_next_error);

            ec.MarkLabel(labels[0]);

            iterator_body_end = ec.DefineLabel();

            block.EmitEmbedded(ec);

            ec.MarkLabel(iterator_body_end);

            if (async_init != null)
            {
                var catch_value = LocalVariable.CreateCompilerGenerated(ec.Module.Compiler.BuiltinTypes.Exception, block, Location);

                ec.BeginCatchBlock(catch_value.Type);
                catch_value.EmitAssign(ec);

                ec.EmitThis();
                ec.EmitInt((int)IteratorStorey.State.After);
                ec.Emit(OpCodes.Stfld, storey.PC.Spec);

                ((AsyncTaskStorey)async_init.Storey).EmitSetException(ec, new LocalVariableReference(catch_value, Location));

                ec.Emit(OpCodes.Leave, move_next_ok);
                ec.EndExceptionBlock();
            }

            ec.Mark(Block.Original.EndLocation);
            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.PC.Spec);

            EmitMoveNextEpilogue(ec);

            ec.MarkLabel(move_next_error);

            if (ReturnType.Kind != MemberKind.Void)
            {
                ec.EmitInt(0);
                ec.Emit(OpCodes.Ret);
            }

            ec.MarkLabel(move_next_ok);

            if (ReturnType.Kind != MemberKind.Void)
            {
                ec.EmitInt(1);
                ec.Emit(OpCodes.Ret);
            }
        }
示例#5
0
文件: iterators.cs 项目: speier/shake
        internal void EmitMoveNext(EmitContext ec, Block original_block)
        {
            move_next_ok = ec.DefineLabel ();
            move_next_error = ec.DefineLabel ();

            if (resume_points == null) {
                EmitMoveNext_NoResumePoints (ec, original_block);
                return;
            }

            current_pc = ec.GetTemporaryLocal (TypeManager.uint32_type);
            ec.Emit (OpCodes.Ldarg_0);
            ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
            ec.Emit (OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt ((int) State.After);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            Label [] labels = new Label [1 + resume_points.Count];
            labels [0] = ec.DefineLabel ();

            bool need_skip_finally = false;
            for (int i = 0; i < resume_points.Count; ++i) {
                ResumableStatement s = resume_points [i];
                need_skip_finally |= s is ExceptionStatement;
                labels [i+1] = s.PrepareForEmit (ec);
            }

            if (need_skip_finally) {
                skip_finally = ec.GetTemporaryLocal (TypeManager.bool_type);
                ec.Emit (OpCodes.Ldc_I4_0);
                ec.Emit (OpCodes.Stloc, skip_finally);
            }

            SymbolWriter.StartIteratorDispatcher (ec);
            ec.Emit (OpCodes.Ldloc, current_pc);
            ec.Emit (OpCodes.Switch, labels);

            ec.Emit (OpCodes.Br, move_next_error);
            SymbolWriter.EndIteratorDispatcher (ec);

            ec.MarkLabel (labels [0]);

            SymbolWriter.StartIteratorBody (ec);
            original_block.Emit (ec);
            SymbolWriter.EndIteratorBody (ec);

            SymbolWriter.StartIteratorDispatcher (ec);

            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt ((int) State.After);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            ec.MarkLabel (move_next_error);
            ec.EmitInt (0);
            ec.Emit (OpCodes.Ret);

            ec.MarkLabel (move_next_ok);
            ec.Emit (OpCodes.Ldc_I4_1);
            ec.Emit (OpCodes.Ret);

            SymbolWriter.EndIteratorDispatcher (ec);
        }
示例#6
0
文件: constant.cs 项目: rabink/mono
		public override void Emit (EmitContext ec)
		{
			MethodSpec m;

			int [] words = decimal.GetBits (Value);
			int power = (words [3] >> 16) & 0xff;

			if (power == 0) {
				if (Value <= int.MaxValue && Value >= int.MinValue) {
					m = ec.Module.PredefinedMembers.DecimalCtorInt.Resolve (loc);
					if (m == null) {
						return;
					}

					ec.EmitInt ((int) Value);
					ec.Emit (OpCodes.Newobj, m);
					return;
				}

				if (Value <= long.MaxValue && Value >= long.MinValue) {
					m = ec.Module.PredefinedMembers.DecimalCtorLong.Resolve (loc);
					if (m == null) {
						return;
					}

					ec.EmitLong ((long) Value);
					ec.Emit (OpCodes.Newobj, m);
					return;
				}
			}

			ec.EmitInt (words [0]);
			ec.EmitInt (words [1]);
			ec.EmitInt (words [2]);

			// sign
			ec.EmitInt (words [3] >> 31);

			// power
			ec.EmitInt (power);

			m = ec.Module.PredefinedMembers.DecimalCtor.Resolve (loc);
			if (m != null) {
				ec.Emit (OpCodes.Newobj, m);
			}
		}
示例#7
0
文件: constant.cs 项目: rabink/mono
		public override void Emit (EmitContext ec)
		{
			if (Value)
				ec.EmitInt (1);
			else
				ec.EmitInt (0);
		}
示例#8
0
		protected sealed override void DoEmit (EmitContext ec)
		{
			EmitPreTryBody (ec);

			if (resume_points != null) {
				ec.EmitInt ((int) Iterator.State.Running);
				ec.Emit (OpCodes.Stloc, iter.CurrentPC);
			}

			ec.BeginExceptionBlock ();

			if (resume_points != null) {
				ec.MarkLabel (resume_point);

				// For normal control flow, we want to fall-through the Switch
				// So, we use CurrentPC rather than the $PC field, and initialize it to an outside value above
				ec.Emit (OpCodes.Ldloc, iter.CurrentPC);
				ec.EmitInt (first_resume_pc);
				ec.Emit (OpCodes.Sub);

				Label [] labels = new Label [resume_points.Count];
				for (int i = 0; i < resume_points.Count; ++i)
					labels [i] = resume_points [i].PrepareForEmit (ec);
				ec.Emit (OpCodes.Switch, labels);
			}

			EmitTryBody (ec);

			ec.BeginFinallyBlock ();

			Label start_finally = ec.DefineLabel ();
			if (resume_points != null) {
				ec.Emit (OpCodes.Ldloc, iter.SkipFinally);
				ec.Emit (OpCodes.Brfalse_S, start_finally);
				ec.Emit (OpCodes.Endfinally);
			}

			ec.MarkLabel (start_finally);
			EmitFinallyBody (ec);

			ec.EndExceptionBlock ();
		}
示例#9
0
		public override void EmitForDispose (EmitContext ec, Iterator iterator, Label end, bool have_dispatcher)
		{
			if (emitted_dispose)
				return;

			emitted_dispose = true;

			Label end_of_try = ec.DefineLabel ();

			// Ensure that the only way we can get into this code is through a dispatcher
			if (have_dispatcher)
				ec.Emit (OpCodes.Br, end);

			ec.BeginExceptionBlock ();

			ec.MarkLabel (dispose_try_block);

			Label [] labels = null;
			for (int i = 0; i < resume_points.Count; ++i) {
				ResumableStatement s = (ResumableStatement) resume_points [i];
				Label ret = s.PrepareForDispose (ec, end_of_try);
				if (ret.Equals (end_of_try) && labels == null)
					continue;
				if (labels == null) {
					labels = new Label [resume_points.Count];
					for (int j = 0; j < i; ++j)
						labels [j] = end_of_try;
				}
				labels [i] = ret;
			}

			if (labels != null) {
				int j;
				for (j = 1; j < labels.Length; ++j)
					if (!labels [0].Equals (labels [j]))
						break;
				bool emit_dispatcher = j < labels.Length;

				if (emit_dispatcher) {
					//SymbolWriter.StartIteratorDispatcher (ec.ig);
					ec.Emit (OpCodes.Ldloc, iterator.CurrentPC);
					ec.EmitInt (first_resume_pc);
					ec.Emit (OpCodes.Sub);
					ec.Emit (OpCodes.Switch, labels);
					//SymbolWriter.EndIteratorDispatcher (ec.ig);
				}

				foreach (ResumableStatement s in resume_points)
					s.EmitForDispose (ec, iterator, end_of_try, emit_dispatcher);
			}

			ec.MarkLabel (end_of_try);

			ec.BeginFinallyBlock ();

			EmitFinallyBody (ec);

			ec.EndExceptionBlock ();
		}
示例#10
0
		void EmitObjectInteger (EmitContext ec, object k)
		{
			if (k is int)
				ec.EmitInt ((int) k);
			else if (k is Constant) {
				EmitObjectInteger (ec, ((Constant) k).GetValue ());
			} 
			else if (k is uint)
				ec.EmitInt (unchecked ((int) (uint) k));
			else if (k is long)
			{
				if ((long) k >= int.MinValue && (long) k <= int.MaxValue)
				{
					ec.EmitInt ((int) (long) k);
					ec.Emit (OpCodes.Conv_I8);
				}
				else
					ec.EmitLong ((long) k);
			}
			else if (k is ulong)
			{
				ulong ul = (ulong) k;
				if (ul < (1L<<32))
				{
					ec.EmitInt (unchecked ((int) ul));
					ec.Emit (OpCodes.Conv_U8);
				}
				else
				{
					ec.EmitLong (unchecked ((long) ul));
				}
			}
			else if (k is char)
				ec.EmitInt ((int) ((char) k));
			else if (k is sbyte)
				ec.EmitInt ((int) ((sbyte) k));
			else if (k is byte)
				ec.EmitInt ((int) ((byte) k));
			else if (k is short)
				ec.EmitInt ((int) ((short) k));
			else if (k is ushort)
				ec.EmitInt ((int) ((ushort) k));
			else if (k is bool)
				ec.EmitInt (((bool) k) ? 1 : 0);
			else
				throw new Exception ("Unhandled case");
		}
示例#11
0
		/// <summary>
		/// This method emits code for a lookup-based switch statement (non-string)
		/// Basically it groups the cases into blocks that are at least half full,
		/// and then spits out individual lookup opcodes for each block.
		/// It emits the longest blocks first, and short blocks are just
		/// handled with direct compares.
		/// </summary>
		/// <param name="ec"></param>
		/// <param name="val"></param>
		/// <returns></returns>
		void TableSwitchEmit (EmitContext ec, Expression val)
		{
			int element_count = Elements.Count;
			object [] element_keys = new object [element_count];
			Elements.Keys.CopyTo (element_keys, 0);
			Array.Sort (element_keys);

			// initialize the block list with one element per key
			var key_blocks = new List<KeyBlock> (element_count);
			foreach (object key in element_keys)
				key_blocks.Add (new KeyBlock (System.Convert.ToInt64 (key)));

			KeyBlock current_kb;
			// iteratively merge the blocks while they are at least half full
			// there's probably a really cool way to do this with a tree...
			while (key_blocks.Count > 1)
			{
				var key_blocks_new = new List<KeyBlock> ();
				current_kb = (KeyBlock) key_blocks [0];
				for (int ikb = 1; ikb < key_blocks.Count; ikb++)
				{
					KeyBlock kb = (KeyBlock) key_blocks [ikb];
					if ((current_kb.Size + kb.Size) * 2 >=  KeyBlock.TotalLength (current_kb, kb))
					{
						// merge blocks
						current_kb.last = kb.last;
						current_kb.Size += kb.Size;
					}
					else
					{
						// start a new block
						key_blocks_new.Add (current_kb);
						current_kb = kb;
					}
				}
				key_blocks_new.Add (current_kb);
				if (key_blocks.Count == key_blocks_new.Count)
					break;
				key_blocks = key_blocks_new;
			}

			// initialize the key lists
			foreach (KeyBlock kb in key_blocks)
				kb.element_keys = new List<object> ();

			// fill the key lists
			int iBlockCurr = 0;
			if (key_blocks.Count > 0) {
				current_kb = (KeyBlock) key_blocks [0];
				foreach (object key in element_keys)
				{
					bool next_block = (key is UInt64) ? (ulong) key > (ulong) current_kb.last :
						System.Convert.ToInt64 (key) > current_kb.last;
					if (next_block)
						current_kb = (KeyBlock) key_blocks [++iBlockCurr];
					current_kb.element_keys.Add (key);
				}
			}

			// sort the blocks so we can tackle the largest ones first
			key_blocks.Sort ();

			// okay now we can start...
			Label lbl_end = ec.DefineLabel ();	// at the end ;-)
			Label lbl_default = default_target;

			Type type_keys = null;
			if (element_keys.Length > 0)
				type_keys = element_keys [0].GetType ();	// used for conversions

			TypeSpec compare_type;
			
			if (TypeManager.IsEnumType (SwitchType))
				compare_type = EnumSpec.GetUnderlyingType (SwitchType);
			else
				compare_type = SwitchType;
			
			for (int iBlock = key_blocks.Count - 1; iBlock >= 0; --iBlock)
			{
				KeyBlock kb = ((KeyBlock) key_blocks [iBlock]);
				lbl_default = (iBlock == 0) ? default_target : ec.DefineLabel ();
				if (kb.Length <= 2)
				{
					foreach (object key in kb.element_keys) {
						SwitchLabel sl = (SwitchLabel) Elements [key];
						if (key is int && (int) key == 0) {
							val.EmitBranchable (ec, sl.GetILLabel (ec), false);
						} else {
							val.Emit (ec);
							EmitObjectInteger (ec, key);
							ec.Emit (OpCodes.Beq, sl.GetILLabel (ec));
						}
					}
				}
				else
				{
					// TODO: if all the keys in the block are the same and there are
					//       no gaps/defaults then just use a range-check.
					if (compare_type == TypeManager.int64_type ||
						compare_type == TypeManager.uint64_type)
					{
						// TODO: optimize constant/I4 cases

						// check block range (could be > 2^31)
						val.Emit (ec);
						EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
						ec.Emit (OpCodes.Blt, lbl_default);
						val.Emit (ec);
						EmitObjectInteger (ec, System.Convert.ChangeType (kb.last, type_keys));
						ec.Emit (OpCodes.Bgt, lbl_default);

						// normalize range
						val.Emit (ec);
						if (kb.first != 0)
						{
							EmitObjectInteger (ec, System.Convert.ChangeType (kb.first, type_keys));
							ec.Emit (OpCodes.Sub);
						}
						ec.Emit (OpCodes.Conv_I4);	// assumes < 2^31 labels!
					}
					else
					{
						// normalize range
						val.Emit (ec);
						int first = (int) kb.first;
						if (first > 0)
						{
							ec.EmitInt (first);
							ec.Emit (OpCodes.Sub);
						}
						else if (first < 0)
						{
							ec.EmitInt (-first);
							ec.Emit (OpCodes.Add);
						}
					}

					// first, build the list of labels for the switch
					int iKey = 0;
					int cJumps = kb.Length;
					Label [] switch_labels = new Label [cJumps];
					for (int iJump = 0; iJump < cJumps; iJump++)
					{
						object key = kb.element_keys [iKey];
						if (System.Convert.ToInt64 (key) == kb.first + iJump)
						{
							SwitchLabel sl = (SwitchLabel) Elements [key];
							switch_labels [iJump] = sl.GetILLabel (ec);
							iKey++;
						}
						else
							switch_labels [iJump] = lbl_default;
					}
					// emit the switch opcode
					ec.Emit (OpCodes.Switch, switch_labels);
				}

				// mark the default for this block
				if (iBlock != 0)
					ec.MarkLabel (lbl_default);
			}

			// TODO: find the default case and emit it here,
			//       to prevent having to do the following jump.
			//       make sure to mark other labels in the default section

			// the last default just goes to the end
			if (element_keys.Length > 0)
				ec.Emit (OpCodes.Br, lbl_default);

			// now emit the code for the sections
			bool found_default = false;

			foreach (SwitchSection ss in Sections) {
				foreach (SwitchLabel sl in ss.Labels) {
					if (sl.Converted == SwitchLabel.NullStringCase) {
						ec.MarkLabel (null_target);
					} else if (sl.Label == null) {
						ec.MarkLabel (lbl_default);
						found_default = true;
						if (!has_null_case)
							ec.MarkLabel (null_target);
					}
					ec.MarkLabel (sl.GetILLabel (ec));
					ec.MarkLabel (sl.GetILLabelCode (ec));
				}
				ss.Block.Emit (ec);
			}
			
			if (!found_default) {
				ec.MarkLabel (lbl_default);
				if (!has_null_case) {
					ec.MarkLabel (null_target);
				}
			}
			
			ec.MarkLabel (lbl_end);
		}
示例#12
0
				protected override void DoEmit (EmitContext ec)
				{
					Label label_init = ec.DefineLabel ();

					ec.Emit (OpCodes.Ldarg_0);
					ec.Emit (OpCodes.Ldflda, host.PC.Spec);
					ec.EmitInt ((int) Iterator.State.Start);
					ec.EmitInt ((int) Iterator.State.Uninitialized);

					var m = ec.Module.PredefinedMembers.InterlockedCompareExchange.Resolve (loc);
					if (m != null)
						ec.Emit (OpCodes.Call, m);

					ec.EmitInt ((int) Iterator.State.Uninitialized);
					ec.Emit (OpCodes.Bne_Un_S, label_init);

					ec.Emit (OpCodes.Ldarg_0);
					ec.Emit (OpCodes.Ret);

					ec.MarkLabel (label_init);

					new_storey.Emit (ec);
					ec.Emit (OpCodes.Ret);
				}
示例#13
0
		//
		// Called back from Yield
		//
		public void MarkYield (EmitContext ec, Expression expr, int resume_pc, bool unwind_protect, Label resume_point)
		{
			// Store the new current
			ec.Emit (OpCodes.Ldarg_0);
			expr.Emit (ec);
			ec.Emit (OpCodes.Stfld, IteratorHost.CurrentField.Spec);

			//
			// Guard against being disposed meantime
			//
			Label disposed = ec.DefineLabel ();
			ec.Emit (OpCodes.Ldarg_0);
			ec.Emit (OpCodes.Ldfld, IteratorHost.DisposingField.Spec);
			ec.Emit (OpCodes.Brtrue_S, disposed);

			//
			// store resume program-counter
			//
			ec.Emit (OpCodes.Ldarg_0);
			ec.EmitInt (resume_pc);
			ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);
			ec.MarkLabel (disposed);

			// mark finally blocks as disabled
			if (unwind_protect && skip_finally != null) {
				ec.EmitInt (1);
				ec.Emit (OpCodes.Stloc, skip_finally);
			}

			// Return ok
			ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_ok);

			ec.MarkLabel (resume_point);
		}
示例#14
0
        public void EmitDispose(EmitContext ec)
        {
            if (resume_points == null)
            {
                return;
            }

            Label end = ec.DefineLabel();

            Label[] labels = null;
            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = resume_points[i];
                Label ret            = s.PrepareForDispose(ec, end);
                if (ret.Equals(end) && labels == null)
                {
                    continue;
                }
                if (labels == null)
                {
                    labels = new Label[resume_points.Count + 1];
                    for (int j = 0; j <= i; ++j)
                    {
                        labels[j] = end;
                    }
                }

                labels[i + 1] = ret;
            }

            if (labels != null)
            {
                current_pc = ec.GetTemporaryLocal(ec.BuiltinTypes.UInt);
                ec.EmitThis();
                ec.Emit(OpCodes.Ldfld, storey.PC.Spec);
                ec.Emit(OpCodes.Stloc, current_pc);
            }

            ec.EmitThis();
            ec.EmitInt(1);
            ec.Emit(OpCodes.Stfld, ((IteratorStorey)storey).DisposingField.Spec);

            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.PC.Spec);

            if (labels != null)
            {
                //SymbolWriter.StartIteratorDispatcher (ec.ig);
                ec.Emit(OpCodes.Ldloc, current_pc);
                ec.Emit(OpCodes.Switch, labels);
                //SymbolWriter.EndIteratorDispatcher (ec.ig);

                foreach (ResumableStatement s in resume_points)
                {
                    s.EmitForDispose(ec, current_pc, end, true);
                }
            }

            ec.MarkLabel(end);
        }
示例#15
0
文件: eval.cs 项目: FrancisVarga/mono
		internal void EmitValueChangedCallback (EmitContext ec, string name, TypeSpec type, Location loc)
		{
			if (listener_id == null)
				listener_id = ListenerProxy.Register (ModificationListener);

			if (listener_proxy_value == null)
				listener_proxy_value = typeof (ListenerProxy).GetMethod ("ValueChanged");

#if STATIC
			throw new NotSupportedException ();
#else
			// object value, int row, int col, string name, int listenerId
			if (type.IsStructOrEnum)
				ec.Emit (OpCodes.Box, type);

			ec.EmitInt (loc.Row);
			ec.EmitInt (loc.Column);
			ec.Emit (OpCodes.Ldstr, name);
			ec.EmitInt (listener_id.Value);
			ec.Emit (OpCodes.Call, listener_proxy_value);
#endif
		}
示例#16
0
文件: iterators.cs 项目: speier/shake
        public override void Emit(EmitContext ec)
        {
            //
            // Load Iterator storey instance
            //
            method.Storey.Instance.Emit (ec);

            //
            // Initialize iterator PC when it's unitialized
            //
            if (IsEnumerable) {
                ec.Emit (OpCodes.Dup);
                ec.EmitInt ((int)State.Uninitialized);

                var field = IteratorHost.PC.Spec;
                if (Storey.MemberName.IsGeneric) {
                    field = MemberCache.GetMember (Storey.Instance.Type, field);
                }

                ec.Emit (OpCodes.Stfld, field);
            }
        }
示例#17
0
文件: constant.cs 项目: rabink/mono
		public override void Emit (EmitContext ec)
		{
			ec.EmitInt (unchecked ((int) Value));
		}
示例#18
0
文件: iterators.cs 项目: speier/shake
        public void EmitDispose(EmitContext ec)
        {
            Label end = ec.DefineLabel ();

            Label [] labels = null;
            int n_resume_points = resume_points == null ? 0 : resume_points.Count;
            for (int i = 0; i < n_resume_points; ++i) {
                ResumableStatement s = (ResumableStatement) resume_points [i];
                Label ret = s.PrepareForDispose (ec, end);
                if (ret.Equals (end) && labels == null)
                    continue;
                if (labels == null) {
                    labels = new Label [resume_points.Count + 1];
                    for (int j = 0; j <= i; ++j)
                        labels [j] = end;
                }
                labels [i+1] = ret;
            }

            if (labels != null) {
                current_pc = ec.GetTemporaryLocal (TypeManager.uint32_type);
                ec.Emit (OpCodes.Ldarg_0);
                ec.Emit (OpCodes.Ldfld, IteratorHost.PC.Spec);
                ec.Emit (OpCodes.Stloc, current_pc);
            }

            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt ((int) State.After);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            if (labels != null) {
                //SymbolWriter.StartIteratorDispatcher (ec.ig);
                ec.Emit (OpCodes.Ldloc, current_pc);
                ec.Emit (OpCodes.Switch, labels);
                //SymbolWriter.EndIteratorDispatcher (ec.ig);

                foreach (ResumableStatement s in resume_points)
                    s.EmitForDispose (ec, this, end, true);
            }

            ec.MarkLabel (end);
        }
示例#19
0
文件: constant.cs 项目: rabink/mono
		public override void Emit (EmitContext ec)
		{
			//
			// Emits null pointer
			//
			ec.EmitInt (0);
			ec.Emit (OpCodes.Conv_U);
		}
示例#20
0
文件: iterators.cs 项目: speier/shake
        //
        // Called back from Yield
        //
        public void MarkYield(EmitContext ec, Expression expr, int resume_pc, bool unwind_protect, Label resume_point)
        {
            // Store the new current
            ec.Emit (OpCodes.Ldarg_0);
            expr.Emit (ec);
            ec.Emit (OpCodes.Stfld, IteratorHost.CurrentField.Spec);

            // store resume program-counter
            ec.Emit (OpCodes.Ldarg_0);
            ec.EmitInt (resume_pc);
            ec.Emit (OpCodes.Stfld, IteratorHost.PC.Spec);

            // mark finally blocks as disabled
            if (unwind_protect && skip_finally != null) {
                ec.EmitInt (1);
                ec.Emit (OpCodes.Stloc, skip_finally);
            }

            // Return ok
            ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, move_next_ok);

            ec.MarkLabel (resume_point);
        }
示例#21
0
文件: constant.cs 项目: rabink/mono
		public override void Emit (EmitContext ec)
		{
			ec.EmitInt (Value);
		}
示例#22
0
        void EmitMoveNext(EmitContext ec)
        {
            move_next_ok    = ec.DefineLabel();
            move_next_error = ec.DefineLabel();

            if (resume_points == null)
            {
                EmitMoveNext_NoResumePoints(ec, block);
                return;
            }

            current_pc = ec.GetTemporaryLocal(ec.BuiltinTypes.UInt);
            ec.Emit(OpCodes.Ldarg_0);
            ec.Emit(OpCodes.Ldfld, IteratorHost.PC.Spec);
            ec.Emit(OpCodes.Stloc, current_pc);

            // We're actually in state 'running', but this is as good a PC value as any if there's an abnormal exit
            ec.Emit(OpCodes.Ldarg_0);
            ec.EmitInt((int)State.After);
            ec.Emit(OpCodes.Stfld, IteratorHost.PC.Spec);

            Label [] labels = new Label [1 + resume_points.Count];
            labels [0] = ec.DefineLabel();

            bool need_skip_finally = false;

            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = resume_points [i];
                need_skip_finally |= s is ExceptionStatement;
                labels [i + 1]     = s.PrepareForEmit(ec);
            }

            if (need_skip_finally)
            {
                skip_finally = ec.GetTemporaryLocal(ec.BuiltinTypes.Bool);
                ec.Emit(OpCodes.Ldc_I4_0);
                ec.Emit(OpCodes.Stloc, skip_finally);
            }

            SymbolWriter.StartIteratorDispatcher(ec);
            ec.Emit(OpCodes.Ldloc, current_pc);
            ec.Emit(OpCodes.Switch, labels);

            ec.Emit(OpCodes.Br, move_next_error);
            SymbolWriter.EndIteratorDispatcher(ec);

            ec.MarkLabel(labels [0]);

            SymbolWriter.StartIteratorBody(ec);
            block.Emit(ec);
            SymbolWriter.EndIteratorBody(ec);

            SymbolWriter.StartIteratorDispatcher(ec);

            ec.Emit(OpCodes.Ldarg_0);
            ec.EmitInt((int)State.After);
            ec.Emit(OpCodes.Stfld, IteratorHost.PC.Spec);

            ec.MarkLabel(move_next_error);
            ec.EmitInt(0);
            ec.Emit(OpCodes.Ret);

            ec.MarkLabel(move_next_ok);
            ec.Emit(OpCodes.Ldc_I4_1);
            ec.Emit(OpCodes.Ret);

            SymbolWriter.EndIteratorDispatcher(ec);
        }