public override void RewriteChildren(ConstructorOrMethodCall constructorOrMethodCall) { // Method calls (including calls to ctors) require special handling: // any push statements that put arguments on the stack actually need // to be popped in the reverse order (reverse to the stack's LIFO semantics). // The code generator generates a push for push statements, but the call instruction // in IL consumes the stack from last argument to first argument. Thus // if the code model had this "push x; push y; M(pop,pop)" keeping the // stack as it is created by this rewriter would end up creating "M(y,x)" // because the arguments are visited left-to-right. var popsFound = 0; foreach (var a in constructorOrMethodCall.Arguments) { if (a is IPopValue) popsFound++; } if (0 < popsFound) { ReverseN(popsFound); } base.RewriteChildren(constructorOrMethodCall); }
/// <summary> /// Called from the type specific rewrite method to rewrite the common part of constructors and method calls. /// </summary> /// <param name="constructorOrMethodCall"></param> public virtual void RewriteChildren(ConstructorOrMethodCall constructorOrMethodCall) { this.RewriteChildren((Expression)constructorOrMethodCall); constructorOrMethodCall.Arguments = this.Rewrite(constructorOrMethodCall.Arguments); constructorOrMethodCall.MethodToCall = this.Rewrite(constructorOrMethodCall.MethodToCall); }