GetTemporaryLocal() public méthode

Returns a temporary storage for a variable of type t as a local variable in the current body.
public GetTemporaryLocal ( System.TypeSpec t ) : LocalBuilder
t System.TypeSpec
Résultat System.Reflection.Emit.LocalBuilder
        public void Store(EmitContext ec)
        {
            if (builder == null)
            {
                builder = ec.GetTemporaryLocal(type);
            }

            ec.Emit(OpCodes.Stloc, builder);
        }
        public void EmitDispose(EmitContext ec)
        {
            ILGenerator ig = ec.ig;

            Label end = ig.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);
                ig.Emit(OpCodes.Ldarg_0);
                ig.Emit(OpCodes.Ldfld, IteratorHost.PC.FieldBuilder);
                ig.Emit(OpCodes.Stloc, current_pc);
            }

            ig.Emit(OpCodes.Ldarg_0);
            IntConstant.EmitInt(ig, (int)State.After);
            ig.Emit(OpCodes.Stfld, IteratorHost.PC.FieldBuilder);

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

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

            ig.MarkLabel(end);
        }
Exemple #3
0
        // NB: if you have `is_address' on the stack there must
        // be a managed pointer. Otherwise, it is the type from
        // the ctor.
        public void Store(EmitContext ec)
        {
            ILGenerator ig = ec.ig;

            if (builder == null)
            {
                builder = ec.GetTemporaryLocal(is_address ? TypeManager.GetReferenceType(type): type);
            }

            ig.Emit(OpCodes.Stloc, builder);
        }
Exemple #4
0
        public void AddressOf(EmitContext ec, AddressOp mode)
        {
            if (builder == null)
            {
                builder = ec.GetTemporaryLocal(type);
            }

            if (builder.LocalType.IsByRef)
            {
                //
                // if is_address, than this is just the address anyways,
                // so we just return this.
                //
                ec.Emit(OpCodes.Ldloc, builder);
            }
            else
            {
                ec.Emit(OpCodes.Ldloca, builder);
            }
        }
Exemple #5
0
        public void AddressOf(EmitContext ec, AddressOp mode)
        {
            if (builder == null)
            {
                builder = ec.GetTemporaryLocal(is_address ? TypeManager.GetReferenceType(type): type);
            }

            // if is_address, than this is just the address anyways,
            // so we just return this.
            ILGenerator ig = ec.ig;

            if (is_address)
            {
                ig.Emit(OpCodes.Ldloc, builder);
            }
            else
            {
                ig.Emit(OpCodes.Ldloca, builder);
            }
        }
Exemple #6
0
        public void Emit(EmitContext ec)
        {
            Nullable.Unwrap unwrap;

            if (NullShortCircuit)
            {
                NullOperatorLabel = ec.DefineLabel();
                unwrap            = instance as Nullable.Unwrap;
            }
            else
            {
                unwrap = null;
            }

            if (unwrap != null)
            {
                unwrap.Store(ec);
                unwrap.EmitCheck(ec);
                ec.Emit(OpCodes.Brfalse, NullOperatorLabel);
                unwrap.Emit(ec);
                var tmp = ec.GetTemporaryLocal(unwrap.Type);
                ec.Emit(OpCodes.Stloc, tmp);
                ec.Emit(OpCodes.Ldloca, tmp);
                ec.FreeTemporaryLocal(tmp, unwrap.Type);
                return;
            }

            EmitLoad(ec);

            if (NullShortCircuit)
            {
                ec.Emit(OpCodes.Dup);
                ec.Emit(OpCodes.Brfalse, NullOperatorLabel);
            }

            value_on_stack = true;
        }
Exemple #7
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);
        }
Exemple #8
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]);

            BodyEnd = ec.DefineLabel();

            block.EmitEmbedded(ec);

            ec.MarkLabel(BodyEnd);

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

            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);
            }
        }
		public void AddressOf (EmitContext ec, AddressOp mode)
		{
			if (builder == null)
				builder = ec.GetTemporaryLocal (is_address ? TypeManager.GetReferenceType (type): type);

			// if is_address, than this is just the address anyways,
			// so we just return this.
			ILGenerator ig = ec.ig;

			if (is_address)
				ig.Emit (OpCodes.Ldloc, builder);
			else
				ig.Emit (OpCodes.Ldloca, builder);
		}
Exemple #10
0
		public void AddressOf (EmitContext ec, AddressOp mode)
		{
			if (builder == null)
				builder = ec.GetTemporaryLocal (type);

			if (builder.LocalType.IsByRef) {
				//
				// if is_address, than this is just the address anyways,
				// so we just return this.
				//
				ec.Emit (OpCodes.Ldloc, builder);
			} else {
				ec.Emit (OpCodes.Ldloca, builder);
			}
		}
Exemple #11
0
        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);
        }
        internal void EmitMoveNext(EmitContext ec, Block original_block)
        {
            ILGenerator ig = ec.ig;

            move_next_ok    = ig.DefineLabel();
            move_next_error = ig.DefineLabel();

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

            current_pc = ec.GetTemporaryLocal(TypeManager.uint32_type);
            ig.Emit(OpCodes.Ldarg_0);
            ig.Emit(OpCodes.Ldfld, IteratorHost.PC.FieldBuilder);
            ig.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
            ig.Emit(OpCodes.Ldarg_0);
            IntConstant.EmitInt(ig, (int)State.After);
            ig.Emit(OpCodes.Stfld, IteratorHost.PC.FieldBuilder);

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

            bool need_skip_finally = false;

            for (int i = 0; i < resume_points.Count; ++i)
            {
                ResumableStatement s = (ResumableStatement)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);
                ig.Emit(OpCodes.Ldc_I4_0);
                ig.Emit(OpCodes.Stloc, skip_finally);
            }

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

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

            ig.MarkLabel(labels [0]);

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

            SymbolWriter.StartIteratorDispatcher(ec.ig);

            ig.Emit(OpCodes.Ldarg_0);
            IntConstant.EmitInt(ig, (int)State.After);
            ig.Emit(OpCodes.Stfld, IteratorHost.PC.FieldBuilder);

            ig.MarkLabel(move_next_error);
            ig.Emit(OpCodes.Ldc_I4_0);
            ig.Emit(OpCodes.Ret);

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

            SymbolWriter.EndIteratorDispatcher(ec.ig);
        }
Exemple #13
0
		public void Emit (EmitContext ec)
		{
			Nullable.Unwrap unwrap;

			if (NullShortCircuit) {
				NullOperatorLabel = ec.DefineLabel ();
				unwrap = instance as Nullable.Unwrap;
			} else {
				unwrap = null;
			}

			if (unwrap != null) {
				unwrap.Store (ec);
				unwrap.EmitCheck (ec);
				ec.Emit (OpCodes.Brfalse, NullOperatorLabel);
				unwrap.Emit (ec);
				var tmp = ec.GetTemporaryLocal (unwrap.Type);
				ec.Emit (OpCodes.Stloc, tmp);
				ec.Emit (OpCodes.Ldloca, tmp);
				ec.FreeTemporaryLocal (tmp, unwrap.Type);
				return;
			}

			EmitLoad (ec);

			if (NullShortCircuit) {
				ec.Emit (OpCodes.Dup);
				ec.Emit (OpCodes.Brfalse, NullOperatorLabel);
			}

			value_on_stack = true;
		}
Exemple #14
0
        public void Emit(EmitContext ec, bool conditionalAccess)
        {
            Label NullOperatorLabel;

            Nullable.Unwrap unwrap;

            if (conditionalAccess && Expression.IsNeverNull(instance))
            {
                conditionalAccess = false;
            }

            if (conditionalAccess)
            {
                NullOperatorLabel = ec.DefineLabel();
                unwrap            = instance as Nullable.Unwrap;
            }
            else
            {
                NullOperatorLabel = new Label();
                unwrap            = null;
            }

            if (unwrap != null)
            {
                unwrap.Store(ec);
                unwrap.EmitCheck(ec);
                ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel);
            }
            else
            {
                EmitLoad(ec);

                if (conditionalAccess)
                {
                    ec.Emit(OpCodes.Dup);
                    ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel);
                    ec.Emit(OpCodes.Pop);
                }
            }

            if (conditionalAccess)
            {
                if (!ec.ConditionalAccess.Statement)
                {
                    if (ec.ConditionalAccess.Type.IsNullableType)
                    {
                        Nullable.LiftedNull.Create(ec.ConditionalAccess.Type, Location.Null).Emit(ec);
                    }
                    else
                    {
                        ec.EmitNull();
                    }
                }

                ec.Emit(OpCodes.Br, ec.ConditionalAccess.EndLabel);
                ec.MarkLabel(NullOperatorLabel);

                if (unwrap != null)
                {
                    unwrap.Emit(ec);
                    var tmp = ec.GetTemporaryLocal(unwrap.Type);
                    ec.Emit(OpCodes.Stloc, tmp);
                    ec.Emit(OpCodes.Ldloca, tmp);
                    ec.FreeTemporaryLocal(tmp, unwrap.Type);
                }
            }
        }
		public override void Emit (EmitContext ec)
		{
			ILGenerator ig = ec.ig;
			Label false_target = ig.DefineLabel ();
			Label end_target = ig.DefineLabel ();

			expr.EmitBranchable (ec, false_target, false);
			true_expr.Emit (ec);

			if (type.IsInterface) {
				LocalBuilder temp = ec.GetTemporaryLocal (type);
				ig.Emit (OpCodes.Stloc, temp);
				ig.Emit (OpCodes.Ldloc, temp);
				ec.FreeTemporaryLocal (temp, type);
			}

			ig.Emit (OpCodes.Br, end_target);
			ig.MarkLabel (false_target);
			false_expr.Emit (ec);
			ig.MarkLabel (end_target);
		}
Exemple #16
0
		public void Emit (EmitContext ec, bool conditionalAccess)
		{
			Label NullOperatorLabel;
			Nullable.Unwrap unwrap;

			if (conditionalAccess && Expression.IsNeverNull (instance))
				conditionalAccess = false;

			if (conditionalAccess) {
				NullOperatorLabel = ec.DefineLabel ();
				unwrap = instance as Nullable.Unwrap;
			} else {
				NullOperatorLabel = new Label ();
				unwrap = null;
			}

			IMemoryLocation instance_address = null;
			bool conditional_access_dup = false;

			if (unwrap != null) {
				unwrap.Store (ec);
				unwrap.EmitCheck (ec);
				ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel);
			} else {
				if (conditionalAccess && addressRequired) {
					//
					// Don't allocate temp variable when instance load is cheap and load and load-address
					// operate on same memory
					//
					instance_address = instance as VariableReference;
					if (instance_address == null)
						instance_address = instance as LocalTemporary;

					if (instance_address == null) {
						EmitLoad (ec, false);
						ec.Emit (OpCodes.Dup);
						ec.EmitLoadFromPtr (instance.Type);

						conditional_access_dup = true;
					} else {
						instance.Emit (ec);
					}
				} else {
					EmitLoad (ec, !conditionalAccess);

					if (conditionalAccess) {
						conditional_access_dup = !IsInexpensiveLoad ();
						if (conditional_access_dup)
							ec.Emit (OpCodes.Dup);
					}
				}

				if (conditionalAccess) {
					if (instance.Type.Kind == MemberKind.TypeParameter)
						ec.Emit (OpCodes.Box, instance.Type);

					ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel);

					if (conditional_access_dup)
						ec.Emit (OpCodes.Pop);
				}
			}

			if (conditionalAccess) {
				if (!ec.ConditionalAccess.Statement) {
					if (ec.ConditionalAccess.Type.IsNullableType)
						Nullable.LiftedNull.Create (ec.ConditionalAccess.Type, Location.Null).Emit (ec);
					else
						ec.EmitNull ();
				}

				ec.Emit (OpCodes.Br, ec.ConditionalAccess.EndLabel);
				ec.MarkLabel (NullOperatorLabel);

				if (instance_address != null) {
					instance_address.AddressOf (ec, AddressOp.Load);
				} else if (unwrap != null) {
					unwrap.Emit (ec);
					var tmp = ec.GetTemporaryLocal (unwrap.Type);
					ec.Emit (OpCodes.Stloc, tmp);
					ec.Emit (OpCodes.Ldloca, tmp);
					ec.FreeTemporaryLocal (tmp, unwrap.Type);
				} else if (!conditional_access_dup) {
					instance.Emit (ec);
				}
			}
		}
Exemple #17
0
        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);
        }
Exemple #18
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.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();
            }

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

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

            ec.MarkLabel(labels[0]);

            iterator_body_end = ec.DefineLabel();

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

            SymbolWriter.StartIteratorDispatcher(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.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);
            }

            SymbolWriter.EndIteratorDispatcher(ec);
        }
Exemple #19
0
		public void Store (EmitContext ec)
		{
			if (builder == null)
				builder = ec.GetTemporaryLocal (type);

			ec.Emit (OpCodes.Stloc, builder);
		}
Exemple #20
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);
        }
Exemple #21
0
        public void Emit(EmitContext ec, bool conditionalAccess)
        {
            Label NullOperatorLabel;

            Nullable.Unwrap unwrap;

            if (conditionalAccess && Expression.IsNeverNull(instance))
            {
                conditionalAccess = false;
            }

            if (conditionalAccess)
            {
                NullOperatorLabel = ec.DefineLabel();
                unwrap            = instance as Nullable.Unwrap;
            }
            else
            {
                NullOperatorLabel = new Label();
                unwrap            = null;
            }

            IMemoryLocation instance_address       = null;
            bool            conditional_access_dup = false;

            if (unwrap != null)
            {
                unwrap.Store(ec);
                unwrap.EmitCheck(ec);
                ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel);
            }
            else
            {
                if (conditionalAccess && addressRequired)
                {
                    //
                    // Don't allocate temp variable when instance load is cheap and load and load-address
                    // operate on same memory
                    //
                    instance_address = instance as VariableReference;
                    if (instance_address == null)
                    {
                        instance_address = instance as LocalTemporary;
                    }

                    if (instance_address == null)
                    {
                        EmitLoad(ec, false);
                        ec.Emit(OpCodes.Dup);
                        ec.EmitLoadFromPtr(instance.Type);

                        conditional_access_dup = true;
                    }
                    else
                    {
                        instance.Emit(ec);
                    }
                }
                else
                {
                    EmitLoad(ec, !conditionalAccess);

                    if (conditionalAccess)
                    {
                        conditional_access_dup = !IsInexpensiveLoad();
                        if (conditional_access_dup)
                        {
                            ec.Emit(OpCodes.Dup);
                        }
                    }
                }

                if (conditionalAccess)
                {
                    if (instance.Type.Kind == MemberKind.TypeParameter)
                    {
                        ec.Emit(OpCodes.Box, instance.Type);
                    }

                    ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel);

                    if (conditional_access_dup)
                    {
                        ec.Emit(OpCodes.Pop);
                    }
                }
            }

            if (conditionalAccess)
            {
                if (!ec.ConditionalAccess.Statement)
                {
                    if (ec.ConditionalAccess.Type.IsNullableType)
                    {
                        Nullable.LiftedNull.Create(ec.ConditionalAccess.Type, Location.Null).Emit(ec);
                    }
                    else
                    {
                        ec.EmitNull();
                    }
                }

                ec.Emit(OpCodes.Br, ec.ConditionalAccess.EndLabel);
                ec.MarkLabel(NullOperatorLabel);

                if (instance_address != null)
                {
                    instance_address.AddressOf(ec, AddressOp.Load);
                }
                else if (unwrap != null)
                {
                    unwrap.Emit(ec);
                    var tmp = ec.GetTemporaryLocal(unwrap.Type);
                    ec.Emit(OpCodes.Stloc, tmp);
                    ec.Emit(OpCodes.Ldloca, tmp);
                    ec.FreeTemporaryLocal(tmp, unwrap.Type);
                }
                else if (!conditional_access_dup)
                {
                    instance.Emit(ec);
                }
            }
        }
		// NB: if you have `is_address' on the stack there must
		// be a managed pointer. Otherwise, it is the type from
		// the ctor.
		public void Store (EmitContext ec)
		{
			ILGenerator ig = ec.ig;
			if (builder == null)
				builder = ec.GetTemporaryLocal (is_address ? TypeManager.GetReferenceType (type): type);

			ig.Emit (OpCodes.Stloc, builder);
		}