public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { object[] vargs = args.Select(arg => arg.Sample).ToArray(); Expression[] eargs = args.Select(arg => arg.Expr).ToArray(); object sample = null; try { sample = callee.Invoke(vargs); } catch (Exception) { } Expression result = new BinOp() { Operation = Kind }; Array.Copy(eargs, result.Children, 2); if (sample != null) result.ResultType = TypeDescriptor.GetTypeOf(sample); else { Type rtype; callee.IsFunction(out rtype); result.ResultType = (TypeDescriptor)rtype; } stack.Push(result, sample); return true; }
/// <summary> /// Determines, how many operands a given CIL instruction will remove from the stack, and how many it will push onto the stack. /// </summary> /// <param name="ili">a CIL instruction</param> /// <param name="method">the method inside whose context the given instruction is executed</param> /// <param name="npop">number of removed stack operands</param> /// <param name="npush">number of stack operands pushed onto the stack</param> public static void GetStackBilance(ILInstruction ili, MethodBase method, out int npop, out int npush) { if (ili.Code.Equals(OpCodes.Ret)) { Type returnType; if (method.IsFunction(out returnType)) npop = 1; else npop = 0; npush = 0; } else if (ili.Code.Equals(OpCodes.Call) || ili.Code.Equals(OpCodes.Calli) || ili.Code.Equals(OpCodes.Callvirt) || ili.Code.Equals(OpCodes.Newobj)) { MethodBase mi = (MethodBase)ili.Operand; ParameterInfo[] pis = mi.GetParameters(); npop = pis.Length; if (ili.Code.Equals(OpCodes.Calli)) ++npop; if (mi.CallingConvention.HasFlag(CallingConventions.HasThis) && !ili.Code.Equals(OpCodes.Newobj)) ++npop; Type returnType; if (mi.IsFunction(out returnType) || ili.Code.Equals(OpCodes.Newobj)) npush = 1; else npush = 0; } else { npop = -StackOperands.GetNumOperands(ili.Code.StackBehaviourPop); npush = StackOperands.GetNumOperands(ili.Code.StackBehaviourPush); } }
public override bool Rewrite(CodeDescriptor decompilee, MethodBase callee, StackElement[] args, IDecompiler stack, IFunctionBuilder builder) { Type returnType; bool flag = callee.IsFunction(out returnType); Debug.Assert(flag); var atype = args[0].Expr.ResultType.CILType; if (atype.IsPointer) atype = atype.GetElementType(); Debug.Assert(atype.Equals(SourceType)); object[] outArgs; object rsample; stack.TryGetReturnValueSample((MethodInfo)callee, args, out outArgs, out rsample); TypeDescriptor rtype; if (rsample != null) rtype = TypeDescriptor.GetTypeOf(rsample); else rtype = returnType; Debug.Assert(rtype.CILType.Equals(DestType)); Expression[] eargs = args.Select(arg => arg.Expr).ToArray(); var fcall = IntrinsicFunctions.Cast(eargs, SourceType, rtype, Reinterpret); stack.Push(fcall, rsample); return true; }