Emit() public method

public Emit ( EmitContext ec ) : void
ec EmitContext
return void
Beispiel #1
0
        public void EmitAwaitOnCompletedDynamic(EmitContext ec, FieldExpr awaiter)
        {
            var critical = Module.PredefinedTypes.ICriticalNotifyCompletion;

            if (!critical.Define())
            {
                throw new NotImplementedException();
            }

            var temp_critical  = new LocalTemporary(critical.TypeSpec);
            var label_critical = ec.DefineLabel();
            var label_end      = ec.DefineLabel();

            //
            // Special path for dynamic awaiters
            //
            // var awaiter = this.$awaiter as ICriticalNotifyCompletion;
            // if (awaiter == null) {
            //    var completion = (INotifyCompletion) this.$awaiter;
            //    this.$builder.AwaitOnCompleted (ref completion, ref this);
            // } else {
            //    this.$builder.AwaitUnsafeOnCompleted (ref awaiter, ref this);
            // }
            //
            awaiter.Emit(ec);
            ec.Emit(OpCodes.Isinst, critical.TypeSpec);
            temp_critical.Store(ec);
            temp_critical.Emit(ec);
            ec.Emit(OpCodes.Brtrue_S, label_critical);

            var temp = new LocalTemporary(Module.PredefinedTypes.INotifyCompletion.TypeSpec);

            awaiter.Emit(ec);
            ec.Emit(OpCodes.Castclass, temp.Type);
            temp.Store(ec);
            EmitOnCompleted(ec, temp, false);
            temp.Release(ec);
            ec.Emit(OpCodes.Br_S, label_end);

            ec.MarkLabel(label_critical);

            EmitOnCompleted(ec, temp_critical, true);

            ec.MarkLabel(label_end);

            temp_critical.Release(ec);
        }
Beispiel #2
0
        //
        // if `dup_args' is true, a copy of the arguments will be left
        // on the stack. If `dup_args' is true, you can specify `this_arg'
        // which will be duplicated before any other args. Only EmitCall
        // should be using this interface.
        //
        public void Emit(EmitContext ec, bool dup_args, LocalTemporary this_arg)
        {
            LocalTemporary[] temps = null;

            if (dup_args && Count != 0)
            {
                temps = new LocalTemporary [Count];
            }

            if (reordered != null && Count > 1)
            {
                foreach (NamedArgument na in reordered)
                {
                    na.EmitAssign(ec);
                }
            }

            int i = 0;

            foreach (Argument a in args)
            {
                a.Emit(ec);
                if (dup_args)
                {
                    ec.ig.Emit(OpCodes.Dup);
                    (temps [i++] = new LocalTemporary(a.Type)).Store(ec);
                }
            }

            if (dup_args)
            {
                if (this_arg != null)
                {
                    this_arg.Emit(ec);
                }

                for (i = 0; i < temps.Length; i++)
                {
                    temps[i].Emit(ec);
                    temps[i].Release(ec);
                }
            }
        }
Beispiel #3
0
		//
		// if `dup_args' is true, a copy of the arguments will be left
		// on the stack. If `dup_args' is true, you can specify `this_arg'
		// which will be duplicated before any other args. Only EmitCall
		// should be using this interface.
		//
		public void Emit (EmitContext ec, bool dup_args, LocalTemporary this_arg)
		{
			LocalTemporary[] temps = null;

			if (dup_args && Count != 0)
				temps = new LocalTemporary [Count];

			if (reordered != null && Count > 1) {
				foreach (NamedArgument na in reordered)
					na.EmitAssign (ec);
			}

			int i = 0;
			foreach (Argument a in args) {
				a.Emit (ec);
				if (dup_args) {
					ec.Emit (OpCodes.Dup);
					(temps [i++] = new LocalTemporary (a.Type)).Store (ec);
				}
			}

			if (dup_args) {
				if (this_arg != null)
					this_arg.Emit (ec);

				for (i = 0; i < temps.Length; i++) {
					temps[i].Emit (ec);
					temps[i].Release (ec);
				}
			}
		}
		bool DoEmitTypeParameter (EmitContext ec)
		{
#if GMCS_SOURCE
			ILGenerator ig = ec.ig;
//			IMemoryLocation ml;

			MethodInfo ci = TypeManager.activator_create_instance.MakeGenericMethod (
				new Type [] { type });

			GenericConstraints gc = TypeManager.GetTypeParameterConstraints (type);
			if (gc.HasReferenceTypeConstraint || gc.HasClassConstraint) {
				ig.Emit (OpCodes.Call, ci);
				return true;
			}

			// Allow DoEmit() to be called multiple times.
			// We need to create a new LocalTemporary each time since
			// you can't share LocalBuilders among ILGeneators.
			LocalTemporary temp = new LocalTemporary (type);

			Label label_activator = ig.DefineLabel ();
			Label label_end = ig.DefineLabel ();

			temp.AddressOf (ec, AddressOp.Store);
			ig.Emit (OpCodes.Initobj, type);

			temp.Emit (ec);
			ig.Emit (OpCodes.Box, type);
			ig.Emit (OpCodes.Brfalse, label_activator);

			temp.AddressOf (ec, AddressOp.Store);
			ig.Emit (OpCodes.Initobj, type);
			temp.Emit (ec);
			ig.Emit (OpCodes.Br_S, label_end);

			ig.MarkLabel (label_activator);

			ig.Emit (OpCodes.Call, ci);
			ig.MarkLabel (label_end);
			return true;
#else
			throw new InternalErrorException ();
#endif
		}
		public override void Emit (EmitContext ec)
		{
			LocalTemporary temp_storage = new LocalTemporary(type);

			temp_storage.AddressOf(ec, AddressOp.LoadStore);
			ec.ig.Emit(OpCodes.Initobj, type);
			temp_storage.Emit(ec);
		}
Beispiel #6
0
		/// <summary>
		///   Emits a list of resolved Arguments that are in the arguments
		///   ArrayList.
		/// 
		///   The MethodBase argument might be null if the
		///   emission of the arguments is known not to contain
		///   a `params' field (for example in constructors or other routines
		///   that keep their arguments in this structure)
		///   
		///   if `dup_args' is true, a copy of the arguments will be left
		///   on the stack. If `dup_args' is true, you can specify `this_arg'
		///   which will be duplicated before any other args. Only EmitCall
		///   should be using this interface.
		/// </summary>
		public static void EmitArguments (EmitContext ec, ArrayList arguments, bool dup_args, LocalTemporary this_arg)
		{
			if (arguments == null)
				return;

			int top = arguments.Count;
			LocalTemporary [] temps = null;
			
			if (dup_args && top != 0)
				temps = new LocalTemporary [top];

			int argument_index = 0;
			Argument a;
			for (int i = 0; i < top; i++) {
				a = (Argument) arguments [argument_index++];
				a.Emit (ec);
				if (dup_args) {
					ec.ig.Emit (OpCodes.Dup);
					(temps [i] = new LocalTemporary (a.Type)).Store (ec);
				}
			}
			
			if (dup_args) {
				if (this_arg != null)
					this_arg.Emit (ec);
				
				for (int i = 0; i < top; i ++) {
					temps [i].Emit (ec);
					temps [i].Release (ec);
				}
			}
		}
				protected override void EmitFinallyBody (EmitContext ec)
				{
					Expression instance = parent.enumerator;
					if (!TypeManager.IsValueType (parent.enumerator_type)) {
						ILGenerator ig = ec.ig;

						parent.enumerator.Emit (ec);

						Label call_dispose = ig.DefineLabel ();

						if (!implements_idisposable) {
							ec.ig.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
							LocalTemporary temp = new LocalTemporary (TypeManager.idisposable_type);
							temp.Store (ec);
							temp.Emit (ec);
							instance = temp;
						}
						
						ig.Emit (OpCodes.Brtrue_S, call_dispose);

						// using 'endfinally' to empty the evaluation stack
						ig.Emit (OpCodes.Endfinally);
						ig.MarkLabel (call_dispose);
					}

					Invocation.EmitCall (ec, false, instance, TypeManager.void_dispose_void, null, loc);
				}