コード例 #1
0
		public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
		{
			throw new NotImplementedException ();
		}
コード例 #2
0
		public override void EmitStatement (EmitContext ec)
		{
			EmitCall (ec, binder_expr, arguments, true);
		}
コード例 #3
0
		//
		// Emits a list of resolved Arguments
		// 
		public void Emit (EmitContext ec)
		{
			Emit (ec, false, false);
		}
コード例 #4
0
		/// <summary>
		///   C# allows this kind of scenarios:
		///   interface I { void M (); }
		///   class X { public void M (); }
		///   class Y : X, I { }
		///
		///   For that case, we create an explicit implementation function
		///   I.M in Y.
		/// </summary>
		void DefineProxy (TypeSpec iface, MethodSpec base_method, MethodSpec iface_method)
		{
			// TODO: Handle nested iface names
			string proxy_name;
			var ns = iface.MemberDefinition.Namespace;
			if (string.IsNullOrEmpty (ns))
				proxy_name = iface.MemberDefinition.Name + "." + iface_method.Name;
			else
				proxy_name = ns + "." + iface.MemberDefinition.Name + "." + iface_method.Name;

			var param = iface_method.Parameters;

			MethodBuilder proxy = container.TypeBuilder.DefineMethod (
				proxy_name,
				MethodAttributes.Private |
				MethodAttributes.HideBySig |
				MethodAttributes.NewSlot |
				MethodAttributes.CheckAccessOnOverride |
				MethodAttributes.Virtual | MethodAttributes.Final,
				CallingConventions.Standard | CallingConventions.HasThis,
				base_method.ReturnType.GetMetaInfo (), param.GetMetaInfo ());

			if (iface_method.IsGeneric) {
				var gnames = iface_method.GenericDefinition.TypeParameters.Select (l => l.Name).ToArray ();
				proxy.DefineGenericParameters (gnames);
			}

			for (int i = 0; i < param.Count; i++) {
				string name = param.FixedParameters [i].Name;
				ParameterAttributes attr = ParametersCompiled.GetParameterAttribute (param.FixedParameters [i].ModFlags);
				proxy.DefineParameter (i + 1, attr, name);
			}

			int top = param.Count;
			var ec = new EmitContext (new ProxyMethodContext (container), proxy.GetILGenerator (), null, null);
			ec.EmitThis ();
			// TODO: GetAllParametersArguments
			for (int i = 0; i < top; i++)
				ec.EmitArgumentLoad (i);

			ec.Emit (OpCodes.Call, base_method);
			ec.Emit (OpCodes.Ret);

			container.TypeBuilder.DefineMethodOverride (proxy, (MethodInfo) iface_method.GetMetaInfo ());
		}
コード例 #5
0
		public void EmitAssign (EmitContext ec)
		{
			ec.EmitArgumentStore (idx);
		}
コード例 #6
0
		public void EmitToVariable (EmitContext ec)
		{
			var type = Expr.Type;
			if (IsByRef) {
				var ml = (IMemoryLocation) Expr;
				ml.AddressOf (ec, AddressOp.LoadStore);
				type = ReferenceContainer.MakeType (ec.Module, type);
			} else {
				Expr.Emit (ec);
			}

			variable = new LocalTemporary (type);
			variable.Store (ec);

			Expr = variable;
		}
コード例 #7
0
        public void EmitPrologue(EmitContext ec)
        {
            awaiter = ((AsyncTaskStorey)machine_initializer.Storey).AddAwaiter(expr.Type, loc);

            var fe_awaiter = new FieldExpr(awaiter, loc);

            fe_awaiter.InstanceExpression = new CompilerGeneratedThis(ec.CurrentType, loc);

            //
            // awaiter = expr.GetAwaiter ();
            //
            using (ec.With(BuilderContext.Options.OmitDebugInfo, true)) {
                fe_awaiter.EmitAssign(ec, expr, false, false);
            }

            Label skip_continuation = ec.DefineLabel();

            Expression completed_expr;

            if (IsDynamic)
            {
                var rc = new ResolveContext(ec.MemberContext);

                Arguments dargs = new Arguments(1);
                dargs.Add(new Argument(fe_awaiter));
                completed_expr = new DynamicMemberBinder("IsCompleted", dargs, loc).Resolve(rc);

                dargs = new Arguments(1);
                dargs.Add(new Argument(completed_expr));
                completed_expr = new DynamicConversion(ec.Module.Compiler.BuiltinTypes.Bool, 0, dargs, loc).Resolve(rc);
            }
            else
            {
                var pe = PropertyExpr.CreatePredefined(awaiter_definition.IsCompleted, loc);
                pe.InstanceExpression = fe_awaiter;
                completed_expr        = pe;
            }

            completed_expr.EmitBranchable(ec, skip_continuation, true);

            base.DoEmit(ec);

            //
            // The stack has to be empty before calling await continuation. We handle this
            // by lifting values which would be left on stack into class fields. The process
            // is quite complicated and quite hard to test because any expression can possibly
            // leave a value on the stack.
            //
            // Following assert fails when some of expression called before is missing EmitToField
            // or parent expression fails to find await in children expressions
            //
            ec.AssertEmptyStack();

            var storey = (AsyncTaskStorey)machine_initializer.Storey;

            if (IsDynamic)
            {
                storey.EmitAwaitOnCompletedDynamic(ec, fe_awaiter);
            }
            else
            {
                storey.EmitAwaitOnCompleted(ec, fe_awaiter);
            }

            // Return ok
            machine_initializer.EmitLeave(ec, unwind_protect);

            ec.MarkLabel(resume_point);
            ec.MarkLabel(skip_continuation);
        }
コード例 #8
0
		public void Emit (EmitContext ec, bool leave_copy)
		{
			throw new NotImplementedException ();
		}
コード例 #9
0
 public override Expression EmitToField(EmitContext ec)
 {
     return(this);
 }
コード例 #10
0
 protected override void DoEmit(EmitContext ec)
 {
     GetResultExpression(ec).Emit(ec);
 }
コード例 #11
0
 public override void EmitStatement(EmitContext ec)
 {
     stmt.EmitStatement(ec);
 }
コード例 #12
0
 public void EmitAssign(EmitContext ec, FieldExpr field)
 {
     stmt.EmitPrologue(ec);
     field.InstanceExpression.Emit(ec);
     stmt.Emit(ec);
 }
コード例 #13
0
 public override Expression EmitToField(EmitContext ec)
 {
     stmt.EmitPrologue(ec);
     return(stmt.GetResultExpression(ec));
 }
コード例 #14
0
		public override void Emit (EmitContext ec)
		{
			var rc = new ResolveContext (ec.MemberContext);
			var expr = new Conditional (new BooleanExpression (condition), invoke, assign, loc).Resolve (rc);
			expr.Emit (ec);
		}
コード例 #15
0
 public override void Emit(EmitContext ec)
 {
     throw new NotImplementedException();
 }
コード例 #16
0
		public override void EmitStatement (EmitContext ec)
		{
			flags |= CSharpBinderFlags.ResultDiscarded;
			base.EmitStatement (ec);
		}
コード例 #17
0
        protected override void EmitMoveNextEpilogue(EmitContext ec)
        {
            var storey = (AsyncTaskStorey)Storey;

            storey.EmitSetResult(ec);
        }
コード例 #18
0
		public void AddressOf (EmitContext ec, AddressOp mode)
		{
			throw new NotImplementedException ();
		}
コード例 #19
0
        public void EmitInitializer(EmitContext ec)
        {
            //
            // Some predefined types are missing
            //
            if (builder == null)
            {
                return;
            }

            var instance      = (TemporaryVariableReference)Instance;
            var builder_field = builder.Spec;

            if (MemberName.Arity > 0)
            {
                builder_field = MemberCache.GetMember(instance.Type, builder_field);
            }

            //
            // Inflated factory method when task is of generic type
            //
            if (builder_factory.DeclaringType.IsGeneric)
            {
                var task_return_type = return_type.TypeArguments;
                var bt = builder_factory.DeclaringType.MakeGenericType(Module, task_return_type);
                builder_factory = MemberCache.GetMember(bt, builder_factory);
                builder_start   = MemberCache.GetMember(bt, builder_start);
            }

            //
            // stateMachine.$builder = AsyncTaskMethodBuilder<{task-type}>.Create();
            //
            instance.AddressOf(ec, AddressOp.Store);
            ec.Emit(OpCodes.Call, builder_factory);
            ec.Emit(OpCodes.Stfld, builder_field);

            //
            // stateMachine.$builder.Start<{storey-type}>(ref stateMachine);
            //
            instance.AddressOf(ec, AddressOp.Store);
            ec.Emit(OpCodes.Ldflda, builder_field);
            if (Task != null)
            {
                ec.Emit(OpCodes.Dup);
            }
            instance.AddressOf(ec, AddressOp.Store);
            ec.Emit(OpCodes.Call, builder_start.MakeGenericMethod(Module, instance.Type));

            //
            // Emits return stateMachine.$builder.Task;
            //
            if (Task != null)
            {
                var task_get = Task.Get;

                if (MemberName.Arity > 0)
                {
                    task_get = MemberCache.GetMember(builder_field.MemberType, task_get);
                }

                var pe_task = new PropertyExpr(Task, Location)
                {
                    InstanceExpression = EmptyExpression.Null,                          // Comes from the dup above
                    Getter             = task_get
                };

                pe_task.Emit(ec);
            }
        }
コード例 #20
0
 void IExpressionCleanup.EmitCleanup(EmitContext ec)
 {
     EmitAssign(ec, new NullConstant(type, loc), false, false);
 }
コード例 #21
0
		protected override void DoEmit (EmitContext ec)
		{
		}
コード例 #22
0
			public override Arguments Emit (EmitContext ec, bool dup_args, bool prepareAwait)
			{
				foreach (var a in ordered) {
					if (prepareAwait)
						a.EmitToField (ec, false);
					else
						a.EmitToVariable (ec);
				}

				return base.Emit (ec, dup_args, prepareAwait);
			}
コード例 #23
0
		public override void Emit (EmitContext ec)
		{
		}
コード例 #24
0
		//
		// if `dup_args' is true or any of arguments contains await.
		// A copy of all arguments will be returned to the caller
		//
		public virtual Arguments Emit (EmitContext ec, bool dup_args, bool prepareAwait)
		{
			List<Argument> dups;

			if ((dup_args && Count != 0) || prepareAwait)
				dups = new List<Argument> (Count);
			else
				dups = null;

			LocalTemporary lt;
			foreach (Argument a in args) {
				if (prepareAwait) {
					dups.Add (a.EmitToField (ec, true));
					continue;
				}
				
				a.Emit (ec);

				if (!dup_args) {
					continue;
				}

				if (a.Expr.IsSideEffectFree) {
					//
					// No need to create a temporary variable for side effect free expressions. I assume
					// all side-effect free expressions are cheap, this has to be tweaked when we become
					// more aggressive on detection
					//
					dups.Add (a);
				} else {
					ec.Emit (OpCodes.Dup);

					// TODO: Release local temporary on next Emit
					// Need to add a flag to argument to indicate this
					lt = new LocalTemporary (a.Type);
					lt.Store (ec);

					dups.Add (new Argument (lt, a.ArgType));
				}
			}

			if (dups != null)
				return new Arguments (dups);

			return null;
		}
コード例 #25
0
//		public override void EmitJs (JsEmitContext jec)
//		{
//		}

		protected override void DoEmit (EmitContext ec)
		{
			throw new NotSupportedException ();
		}
コード例 #26
0
		public override void Emit (EmitContext ec)
		{
			throw new NotImplementedException ();
		}
コード例 #27
0
		protected override void DoEmit (EmitContext ec)
		{
			if (!expr.IsSideEffectFree) {
				expr.EmitSideEffect (ec);
			}
		}
コード例 #28
0
		public override void Emit (EmitContext ec)
		{
			EmitCall (ec, binder_expr, arguments,  false);
		}
コード例 #29
0
		public override void EmitStatement (EmitContext ec)
		{
			throw new System.NotImplementedException ();
		}
コード例 #30
0
		protected void EmitCall (EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
		{
			//
			// This method generates all internal infrastructure for a dynamic call. The
			// reason why it's quite complicated is the mixture of dynamic and anonymous
			// methods. Dynamic itself requires a temporary class (ContainerX) and anonymous
			// methods can generate temporary storey as well (AnonStorey). Handling MVAR
			// type parameters rewrite is non-trivial in such case as there are various
			// combinations possible therefore the mutator is not straightforward. Secondly
			// we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit
			// correct Site field type and its access from EmitContext.
			//

			int dyn_args_count = arguments == null ? 0 : arguments.Count;
			int default_args = isStatement ? 1 : 2;
			var module = ec.Module;

			bool has_ref_out_argument = false;
			var targs = new TypeExpression[dyn_args_count + default_args];
			targs[0] = new TypeExpression (module.PredefinedTypes.CallSite.TypeSpec, loc);

			TypeExpression[] targs_for_instance = null;
			TypeParameterMutator mutator;

			var site_container = ec.CreateDynamicSite ();

			if (context_mvars != null) {
				TypeParameters tparam;
				TypeContainer sc = site_container;
				do {
					tparam = sc.CurrentTypeParameters;
					sc = sc.Parent;
				} while (tparam == null);

				mutator = new TypeParameterMutator (context_mvars, tparam);

				if (!ec.IsAnonymousStoreyMutateRequired) {
					targs_for_instance = new TypeExpression[targs.Length];
					targs_for_instance[0] = targs[0];
				}
			} else {
				mutator = null;
			}

			for (int i = 0; i < dyn_args_count; ++i) {
				Argument a = arguments[i];
				if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
					has_ref_out_argument = true;

				var t = a.Type;

				// Convert any internal type like dynamic or null to object
				if (t.Kind == MemberKind.InternalCompilerType)
					t = ec.BuiltinTypes.Object;

				if (targs_for_instance != null)
					targs_for_instance[i + 1] = new TypeExpression (t, loc);

				if (mutator != null)
					t = t.Mutate (mutator);

				targs[i + 1] = new TypeExpression (t, loc);
			}

			TypeExpr del_type = null;
			TypeExpr del_type_instance_access = null;
			if (!has_ref_out_argument) {
				string d_name = isStatement ? "Action" : "Func";

				TypeExpr te = null;
				Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true);
				if (type_ns != null) {
					te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc);
				}

				if (te != null) {
					if (!isStatement) {
						var t = type;
						if (t.Kind == MemberKind.InternalCompilerType)
							t = ec.BuiltinTypes.Object;

						if (targs_for_instance != null)
							targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression (t, loc);

						if (mutator != null)
							t = t.Mutate (mutator);

						targs[targs.Length - 1] = new TypeExpression (t, loc);
					}

					del_type = new GenericTypeExpr (te.Type, new TypeArguments (targs), loc);
					if (targs_for_instance != null)
						del_type_instance_access = new GenericTypeExpr (te.Type, new TypeArguments (targs_for_instance), loc);
					else
						del_type_instance_access = del_type;
				}
			}

			//
			// Create custom delegate when no appropriate predefined delegate has been found
			//
			Delegate d;
			if (del_type == null) {
				TypeSpec rt = isStatement ? ec.BuiltinTypes.Void : type;
				Parameter[] p = new Parameter[dyn_args_count + 1];
				p[0] = new Parameter (targs[0], "p0", Parameter.Modifier.NONE, null, loc);

				var site = ec.CreateDynamicSite ();
				int index = site.Containers == null ? 0 : site.Containers.Count;

				if (mutator != null)
					rt = mutator.Mutate (rt);

				for (int i = 1; i < dyn_args_count + 1; ++i) {
					p[i] = new Parameter (targs[i], "p" + i.ToString ("X"), arguments[i - 1].Modifier, null, loc);
				}

				d = new Delegate (site, new TypeExpression (rt, loc),
					Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
					new MemberName ("Container" + index.ToString ("X")),
					new ParametersCompiled (p), null);

				d.CreateContainer ();
				d.DefineContainer ();
				d.Define ();

				site.AddTypeContainer (d);
				del_type = new TypeExpression (d.CurrentType, loc);
				if (targs_for_instance != null) {
					del_type_instance_access = null;
				} else {
					del_type_instance_access = del_type;
				}
			} else {
				d = null;
			}

			var site_type_decl = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type), loc);
			var field = site_container.CreateCallSiteField (site_type_decl, loc);
			if (field == null)
				return;

			if (del_type_instance_access == null) {
				var dt = d.CurrentType.DeclaringType.MakeGenericType (module, context_mvars.Types);
				del_type_instance_access = new TypeExpression (MemberCache.GetMember (dt, d.CurrentType), loc);
			}

			var instanceAccessExprType = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec,
				new TypeArguments (del_type_instance_access), loc);

			if (instanceAccessExprType.ResolveAsType (ec.MemberContext) == null)
				return;

			bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

			TypeSpec gt;
			if (inflate_using_mvar || context_mvars == null) {
				gt = site_container.CurrentType;
			} else {
				gt = site_container.CurrentType.MakeGenericType (module, context_mvars.Types);
			}

			// When site container already exists the inflated version has to be
			// updated manually to contain newly created field
			if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) {
				var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
				var inflator = new TypeParameterInflator (module, gt, tparams, gt.TypeArguments);
				gt.MemberCache.AddMember (field.InflateMember (inflator));
			}

			FieldExpr site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc);

			BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void);

			Arguments args = new Arguments (1);
			args.Add (new Argument (binder));
			StatementExpression s = new StatementExpression (new SimpleAssign (site_field_expr, new Invocation (new MemberAccess (instanceAccessExprType, "Create"), args)));

			using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
				if (s.Resolve (bc)) {
					Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
					init.Emit (ec);
				}

				args = new Arguments (1 + dyn_args_count);
				args.Add (new Argument (site_field_expr));
				if (arguments != null) {
					int arg_pos = 1;
					foreach (Argument a in arguments) {
						if (a is NamedArgument) {
							// Name is not valid in this context
							args.Add (new Argument (a.Expr, a.ArgType));
						} else {
							args.Add (a);
						}

						if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
							a.Expr.Type = targs[arg_pos].Type;

						++arg_pos;
					}
				}

				Expression target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, loc).Resolve (bc);
				if (target != null)
					target.Emit (ec);
			}
		}
コード例 #31
0
		public override void Emit (EmitContext ec)
		{
			throw new NotSupportedException ();
		}
コード例 #32
0
		public override void EmitStatement (EmitContext ec)
		{
			var stmt = new If (condition, new StatementExpression (invoke), new StatementExpression (assign), loc);
			using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
				stmt.Emit (ec);
			}
		}
コード例 #33
0
		public override void Emit (EmitContext ec)
		{
			throw new InternalErrorException ("Missing Resolve call");
		}
コード例 #34
0
		public override void EmitStatement (EmitContext ec)
		{
			// It's null for ResolveLValue used without assignment
			if (binder_expr == null)
				EmitCall (ec, setter, Arguments, true);
			else
				base.EmitStatement (ec);
		}
コード例 #35
0
		public virtual void Emit (EmitContext ec)
		{
			if (!IsByRef) {
				Expr.Emit (ec);
				return;
			}

			AddressOp mode = AddressOp.Store;
			if (ArgType == AType.Ref)
				mode |= AddressOp.Load;

			IMemoryLocation ml = (IMemoryLocation) Expr;
			ml.AddressOf (ec, mode);
		}
コード例 #36
0
		public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
		{
			EmitCall (ec, setter, setter_args, !leave_copy);
		}
コード例 #37
0
		public Argument EmitToField (EmitContext ec, bool cloneResult)
		{
			var res = Expr.EmitToField (ec);
			if (cloneResult && res != Expr)
				return new Argument (res, ArgType);

			Expr = res;
			return this;
		}
コード例 #38
0
		public void Emit (EmitContext ec)
		{
			ec.EmitArgumentLoad (idx);
		}
コード例 #39
0
		public override void Emit (EmitContext ec)
		{
			// TODO: Should guard against multiple emits
			base.Emit (ec);

			// Release temporary variable when used
			if (variable != null)
				variable.Release (ec);
		}
コード例 #40
0
		public void EmitAddressOf (EmitContext ec)
		{
			if ((ModFlags & Modifier.RefOutMask) != 0) {
				ec.EmitArgumentLoad (idx);
			} else {
				ec.EmitArgumentAddress (idx);
			}
		}
コード例 #41
0
        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);
        }