Mark() public méthode

This is called immediately before emitting an IL opcode to tell the symbol writer to which source line this opcode belongs.
public Mark ( Mono.CSharp.Location loc ) : void
loc Mono.CSharp.Location
Résultat void
Exemple #1
0
        public override void EmitStatement(EmitContext ec)
        {
            if (resolved == null)
            {
                return;
            }

            //
            // Emit sequence symbol info even if we are in compiler generated
            // block to allow debugging field initializers when constructor is
            // compiler generated
            //
            if (ec.HasSet(BuilderContext.Options.OmitDebugInfo) && ec.HasMethodSymbolBuilder)
            {
                using (ec.With(BuilderContext.Options.OmitDebugInfo, false)) {
                    ec.Mark(loc);
                }
            }

            if (resolved != this)
            {
                resolved.EmitStatement(ec);
            }
            else
            {
                base.EmitStatement(ec);
            }
        }
Exemple #2
0
        void EmitMoveNext_NoResumePoints(EmitContext ec)
        {
            ec.EmitThis();
            ec.Emit(OpCodes.Ldfld, storey.PC.Spec);

            ec.EmitThis();
            ec.EmitInt((int)IteratorStorey.State.After);
            ec.Emit(OpCodes.Stfld, storey.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);

            iterator_body_end = ec.DefineLabel();

            if (ec.EmitAccurateDebugInfo && ec.Mark(Block.Original.StartLocation))
            {
                ec.Emit(OpCodes.Nop);
            }

            block.Emit(ec);

            ec.MarkLabel(iterator_body_end);

            EmitMoveNextEpilogue(ec);

            ec.MarkLabel(move_next_error);

            if (ReturnType.Kind != MemberKind.Void)
            {
                ec.EmitInt(0);
                ec.Emit(OpCodes.Ret);
            }
        }
Exemple #3
0
		public override void Emit (EmitContext ec)
		{
			// It can be null for static initializers
			if (base_ctor == null)
				return;
			
			ec.Mark (loc);

			Invocation.EmitCall (ec, new CompilerGeneratedThis (type, loc), base_ctor, argument_list, loc);
		}
Exemple #4
0
		public override void EmitStatement (EmitContext ec)
		{
			if (resolved == null)
				return;

			//
			// Emit sequence symbol info even if we are in compiler generated
			// block to allow debugging field initializers when constructor is
			// compiler generated
			//
			if (ec.HasSet (BuilderContext.Options.OmitDebugInfo) && ec.HasMethodSymbolBuilder) {
				using (ec.With (BuilderContext.Options.OmitDebugInfo, false)) {
					ec.Mark (loc);
				}
			}

			if (resolved != this)
				resolved.EmitStatement (ec);
			else
				base.EmitStatement (ec);
		}
Exemple #5
0
		protected override void DoEmit (EmitContext ec)
		{
			if (empty) {
				expr.EmitSideEffect (ec);
				return;
			}

			Label old_begin = ec.LoopBegin;
			Label old_end = ec.LoopEnd;
			
			ec.LoopBegin = ec.DefineLabel ();
			ec.LoopEnd = ec.DefineLabel ();

			//
			// Inform whether we are infinite or not
			//
			if (expr is Constant){
				// expr is 'true', since the 'empty' case above handles the 'false' case
				ec.MarkLabel (ec.LoopBegin);
				expr.EmitSideEffect (ec);
				Statement.Emit (ec);
				ec.Emit (OpCodes.Br, ec.LoopBegin);
					
				//
				// Inform that we are infinite (ie, `we return'), only
				// if we do not `break' inside the code.
				//
				ec.MarkLabel (ec.LoopEnd);
			} else {
				Label while_loop = ec.DefineLabel ();

				ec.Emit (OpCodes.Br, ec.LoopBegin);
				ec.MarkLabel (while_loop);

				Statement.Emit (ec);
			
				ec.MarkLabel (ec.LoopBegin);
				ec.Mark (loc);

				expr.EmitBranchable (ec, while_loop, true);
				
				ec.MarkLabel (ec.LoopEnd);
			}	

			ec.LoopBegin = old_begin;
			ec.LoopEnd = old_end;
		}
Exemple #6
0
		public virtual void Emit (EmitContext ec)
		{
			ec.Mark (loc);
			DoEmit (ec);
		}
Exemple #7
0
		public override void Emit (EmitContext ec)
		{
			if (scope_initializers != null)
				EmitScopeInitializers (ec);

			ec.Mark (StartLocation);
			DoEmit (ec);

			if (SymbolWriter.HasSymbolWriter)
				EmitSymbolInfo (ec);
		}
Exemple #8
0
		public override void Emit (EmitContext ec)
		{
			if (Report.Errors > 0)
				return;

#if PRODUCTION
			try {
#endif
			if (ec.HasReturnLabel)
				ec.ReturnLabel = ec.DefineLabel ();

			base.Emit (ec);

			ec.Mark (EndLocation);

			if (ec.HasReturnLabel)
				ec.MarkLabel (ec.ReturnLabel);

			if (ec.return_value != null) {
				ec.Emit (OpCodes.Ldloc, ec.return_value);
				ec.Emit (OpCodes.Ret);
			} else {
				//
				// If `HasReturnLabel' is set, then we already emitted a
				// jump to the end of the method, so we must emit a `ret'
				// there.
				//
				// Unfortunately, System.Reflection.Emit automatically emits
				// a leave to the end of a finally block.  This is a problem
				// if no code is following the try/finally block since we may
				// jump to a point after the end of the method.
				// As a workaround, we're always creating a return label in
				// this case.
				//

				if (ec.HasReturnLabel || !unreachable) {
					if (ec.ReturnType != TypeManager.void_type)
						ec.Emit (OpCodes.Ldloc, ec.TemporaryReturn ());
					ec.Emit (OpCodes.Ret);
				}
			}

#if PRODUCTION
			} catch (Exception e){
				Console.WriteLine ("Exception caught by the compiler while emitting:");
				Console.WriteLine ("   Block that caused the problem begin at: " + block.loc);
					
				Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
				throw;
			}
#endif
		}
Exemple #9
0
        public override void Emit(EmitContext ec)
        {
            // It can be null for static initializers
            if (base_constructor_group == null)
                return;

            ec.Mark (loc);

            base_constructor_group.EmitCall (ec, argument_list);
        }
Exemple #10
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);
            }
        }
Exemple #11
0
		public override void Emit (EmitContext ec)
		{
			// It can be null for static initializers
			if (base_ctor == null)
				return;
			
			ec.Mark (loc);

			var call = new CallEmitter ();
			call.InstanceExpression = new CompilerGeneratedThis (type, loc); 
			call.EmitPredefined (ec, base_ctor, argument_list);
		}
Exemple #12
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();

            if (ec.EmitAccurateDebugInfo && ec.Mark(Block.Original.StartLocation))
            {
                ec.Emit(OpCodes.Nop);
            }

            block.Emit(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);
            }
        }
		public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments, Location? loc = null)
		{
			Expression instance_copy = null;

			if (!HasAwaitArguments && ec.HasSet (BuilderContext.Options.AsyncBody)) {
				HasAwaitArguments = Arguments != null && Arguments.ContainsEmitWithAwait ();
				if (HasAwaitArguments && InstanceExpressionOnStack) {
					throw new NotSupportedException ();
				}
			}

			OpCode call_op;
			LocalTemporary lt = null;

			if (method.IsStatic) {
				call_op = OpCodes.Call;
			} else {
				if (IsVirtualCallRequired (InstanceExpression, method)) {
					call_op = OpCodes.Callvirt;
				} else {
					call_op = OpCodes.Call;
				}

				if (HasAwaitArguments) {
					instance_copy = InstanceExpression.EmitToField (ec);
					if (Arguments == null)
						EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op);
				} else if (!InstanceExpressionOnStack) {
					var instance_on_stack_type = EmitCallInstance (ec, InstanceExpression, method.DeclaringType, call_op);

					if (DuplicateArguments) {
						ec.Emit (OpCodes.Dup);
						if (Arguments != null && Arguments.Count != 0) {
							lt = new LocalTemporary (instance_on_stack_type);
							lt.Store (ec);
							instance_copy = lt;
						}
					}
				}
			}

			if (Arguments != null && !InstanceExpressionOnStack) {
				EmittedArguments = Arguments.Emit (ec, DuplicateArguments, HasAwaitArguments);
				if (EmittedArguments != null) {
					if (instance_copy != null) {
						EmitCallInstance (ec, instance_copy, method.DeclaringType, call_op);

						if (lt != null)
							lt.Release (ec);
					}

					EmittedArguments.Emit (ec);
				}
			}

			if (call_op == OpCodes.Callvirt && (InstanceExpression.Type.IsGenericParameter || InstanceExpression.Type.IsStruct)) {
				ec.Emit (OpCodes.Constrained, InstanceExpression.Type);
			}

			if (loc != null) {
				//
				// Emit explicit sequence point for expressions like Foo.Bar () to help debugger to
				// break at right place when LHS expression can be stepped-into
				//
				// TODO: The list is probably not comprehensive, need to do more testing
				//
				if (InstanceExpression is PropertyExpr || InstanceExpression is Invocation || InstanceExpression is IndexerExpr ||
					InstanceExpression is New || InstanceExpression is DelegateInvocation)
					ec.Mark (loc.Value);
			}

			//
			// Set instance expression to actual result expression. When it contains await it can be
			// picked up by caller
			//
			InstanceExpression = instance_copy;

			if (method.Parameters.HasArglist) {
				var varargs_types = GetVarargsTypes (method, Arguments);
				ec.Emit (call_op, method, varargs_types);
				return;
			}

			//
			// If you have:
			// this.DoFoo ();
			// and DoFoo is not virtual, you can omit the callvirt,
			// because you don't need the null checking behavior.
			//
			ec.Emit (call_op, method);
		}
        public void EmitPredefined(EmitContext ec, MethodSpec method, Arguments Arguments, Location?loc = null)
        {
            Expression instance_copy = null;

            if (!HasAwaitArguments && ec.HasSet(BuilderContext.Options.AsyncBody))
            {
                HasAwaitArguments = Arguments != null && Arguments.ContainsEmitWithAwait();
                if (HasAwaitArguments && InstanceExpressionOnStack)
                {
                    throw new NotSupportedException();
                }
            }

            OpCode         call_op;
            LocalTemporary lt = null;

            if (method.IsStatic)
            {
                call_op = OpCodes.Call;
            }
            else
            {
                if (IsVirtualCallRequired(InstanceExpression, method))
                {
                    call_op = OpCodes.Callvirt;
                }
                else
                {
                    call_op = OpCodes.Call;
                }

                if (HasAwaitArguments)
                {
                    instance_copy = InstanceExpression.EmitToField(ec);
                    if (Arguments == null)
                    {
                        EmitCallInstance(ec, instance_copy, method.DeclaringType, call_op);
                    }
                }
                else if (!InstanceExpressionOnStack)
                {
                    var instance_on_stack_type = EmitCallInstance(ec, InstanceExpression, method.DeclaringType, call_op);

                    if (DuplicateArguments)
                    {
                        ec.Emit(OpCodes.Dup);
                        if (Arguments != null && Arguments.Count != 0)
                        {
                            lt = new LocalTemporary(instance_on_stack_type);
                            lt.Store(ec);
                            instance_copy = lt;
                        }
                    }
                }
            }

            if (Arguments != null && !InstanceExpressionOnStack)
            {
                EmittedArguments = Arguments.Emit(ec, DuplicateArguments, HasAwaitArguments);
                if (EmittedArguments != null)
                {
                    if (instance_copy != null)
                    {
                        EmitCallInstance(ec, instance_copy, method.DeclaringType, call_op);

                        if (lt != null)
                        {
                            lt.Release(ec);
                        }
                    }

                    EmittedArguments.Emit(ec);
                }
            }

            if (call_op == OpCodes.Callvirt && (InstanceExpression.Type.IsGenericParameter || InstanceExpression.Type.IsStruct))
            {
                ec.Emit(OpCodes.Constrained, InstanceExpression.Type);
            }

            if (loc != null)
            {
                //
                // Emit explicit sequence point for expressions like Foo.Bar () to help debugger to
                // break at right place when LHS expression can be stepped-into
                //
                // TODO: The list is probably not comprehensive, need to do more testing
                //
                if (InstanceExpression is PropertyExpr || InstanceExpression is Invocation || InstanceExpression is IndexerExpr ||
                    InstanceExpression is New || InstanceExpression is DelegateInvocation)
                {
                    ec.Mark(loc.Value);
                }
            }

            //
            // Set instance expression to actual result expression. When it contains await it can be
            // picked up by caller
            //
            InstanceExpression = instance_copy;

            if (method.Parameters.HasArglist)
            {
                var varargs_types = GetVarargsTypes(method, Arguments);
                ec.Emit(call_op, method, varargs_types);
                return;
            }

            //
            // If you have:
            // this.DoFoo ();
            // and DoFoo is not virtual, you can omit the callvirt,
            // because you don't need the null checking behavior.
            //
            ec.Emit(call_op, method);
        }
Exemple #15
0
		public void Emit (EmitContext ec)
		{
			if (parent_constructor != null){
				ec.Mark (loc, false);
				if (ec.IsStatic)
					Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
				else
					Invocation.EmitCall (ec, true, false, ec.This, parent_constructor, argument_list, loc);
			}
		}
Exemple #16
0
		public override void Emit (EmitContext ec)
		{
			base.Emit (ec);
			ec.Mark (EndLocation);
		}
Exemple #17
0
		public override void Emit (EmitContext ec)
		{
			Block prev_block = ec.CurrentBlock;
			ec.CurrentBlock = this;

			if (scope_initializers != null) {
				SymbolWriter.OpenCompilerGeneratedBlock (ec.ig);

				using (ec.Set (EmitContext.Flags.OmitDebuggingInfo)) {
					foreach (Statement s in scope_initializers)
						s.Emit (ec);
				}

				SymbolWriter.CloseCompilerGeneratedBlock (ec.ig);
			}

			ec.Mark (StartLocation);
			DoEmit (ec);

			if (SymbolWriter.HasSymbolWriter)
				EmitSymbolInfo (ec);

			ec.CurrentBlock = prev_block;
		}