Пример #1
0
        private static void BeginCall(TranslationContext context, CallInstructionInfo call)
        {
            var code = (context.Provider.LoadReceiver(call.Method, call.IsNewobj) ?? Enumerable.Empty <IInstruction>()).ToArray();

            bool canSwap = false;

            if (code.Length > 0)
            {
                canSwap = true;
                context.Emit(code);
            }

            context.Emit(context.Provider.BeginCall(call.Method));

            if (canSwap && call.SwapAfter)
            {
                context.EmitSwap();
            }
        }
Пример #2
0
        /// <summary>
        /// Performs analysis of given call instruction
        /// </summary>
        /// <param name="currentBlock"></param>
        /// <param name="instr"></param>
        /// <param name="stack"></param>
        /// <param name="context"></param>
        private static void AnalyzeCallInstruction(Node currentBlock, Instruction instr, EvalStack stack, Context context)
        {
            var method = instr.Method;

            if (method == null)
            {
                throw new ILTranslatorException(string.Format("Instruction {0} has no method", instr.Code));
            }

            int n    = method.Parameters.Count;
            var type = method.DeclaringType;

            bool isGetTypeFromHandle = method.IsGetTypeFromHandle();

            var last = instr;

            for (int i = n - 1; i >= 0; --i)
            {
                var p   = method.Parameters[i];
                var arg = stack.Pop();
                last = arg.Last;
                SetParam(currentBlock, arg.Instruction, p, method, context);
                p.Instruction = arg.Instruction;
                //p.Instruction = last;

                if (isGetTypeFromHandle && !arg.IsTypeToken)
                {
                    isGetTypeFromHandle = false;
                }
            }

            if (instr.HasReceiver())
            {
                var r = stack.Pop();
                last = r.Last;
                r.Instruction.ReceiverFor = instr;
                r.Instruction.BoxingType  = ResolveBoxingType(instr, type, context);
            }

            last = FixReceiverInsertPoint(currentBlock, last, method);
            if (!(method.IsInitializeArray() || isGetTypeFromHandle))
            {
                Instruction dup;
                if (IsDup(stack, out dup))
                {
                    var call = new CallInstructionInfo(method, instr)
                    {
                        SwapAfter = true
                    };
                    dup.EndStack.Push(call);
                }
                else
                {
                    last.BeginStack.Push(new CallInstructionInfo(method, instr));
                }
            }

            if (instr.HasReturnValue())
            {
                stack.Push(new EvalItem(instr, last));
            }
        }