/// <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)); } }
public object Pop(bool copy) { var value = EvalStack.Pop(); return(copy ? value.Copy() : value); }