From d091723f6aca642902dd9c7e791cb4b7e2accc7b Mon Sep 17 00:00:00 2001 From: Sergey Andreenko Date: Fri, 24 Feb 2017 13:39:36 -0800 Subject: [PATCH] coreRT fat pointer hidden argument fix for calls with retBufArg Commit migrated from https://github.com/dotnet/coreclr/commit/792ffd6ac53ac576bc6893185c2bcaa68c589fa8 --- src/coreclr/src/jit/flowgraph.cpp | 55 +++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/coreclr/src/jit/flowgraph.cpp b/src/coreclr/src/jit/flowgraph.cpp index 97570c4..3749ba3 100644 --- a/src/coreclr/src/jit/flowgraph.cpp +++ b/src/coreclr/src/jit/flowgraph.cpp @@ -24469,7 +24469,7 @@ private: // fixedFptrAddress - pointer to the tuple // // Return Value: - // loaded hidden argument. + // generic context hidden argument. GenTreePtr GetHiddenArgument(GenTreePtr fixedFptrAddress) { GenTreePtr fixedFptrAddressCopy = compiler->gtCloneExpr(fixedFptrAddress); @@ -24485,7 +24485,7 @@ private: // // Arguments: // actualCallAddress - fixed call address - // hiddenArgument - loaded hidden argument + // hiddenArgument - generic context hidden argument // // Return Value: // created call node. @@ -24495,13 +24495,58 @@ private: GenTreePtr fatTree = fatStmt->gtStmtExpr; GenTreeCall* fatCall = GetCall(fatStmt); fatCall->gtCallAddr = actualCallAddress; - GenTreeArgList* args = fatCall->gtCallArgs; - args = compiler->gtNewListNode(hiddenArgument, args); - fatCall->gtCallArgs = args; + AddHiddenArgument(fatCall, hiddenArgument); return fatStmt; } //------------------------------------------------------------------------ + // AddHiddenArgument: add hidden argument to the call argument list. + // + // Arguments: + // fatCall - fat call node + // hiddenArgument - generic context hidden argument + // + void AddHiddenArgument(GenTreeCall* fatCall, GenTreePtr hiddenArgument) + { + GenTreeArgList* oldArgs = fatCall->gtCallArgs; + GenTreeArgList* newArgs; +#if USER_ARGS_COME_LAST + if (fatCall->HasRetBufArg()) + { + GenTreePtr retBuffer = oldArgs->Current(); + GenTreeArgList* rest = oldArgs->Rest(); + newArgs = compiler->gtNewListNode(hiddenArgument, rest); + newArgs = compiler->gtNewListNode(retBuffer, newArgs); + } + else + { + newArgs = compiler->gtNewListNode(hiddenArgument, oldArgs); + } +#else + newArgs = oldArgs; + AddArgumentToTail(newArgs, hiddenArgument); +#endif + fatCall->gtCallArgs = newArgs; + } + + //------------------------------------------------------------------------ + // AddArgumentToTail: add hidden argument to the tail of the call argument list. + // + // Arguments: + // argList - fat call node + // hiddenArgument - generic context hidden argument + // + void AddArgumentToTail(GenTreeArgList* argList, GenTreePtr hiddenArgument) + { + GenTreeArgList* iterator = argList; + while (iterator->Rest()) + { + iterator = iterator->Rest(); + } + iterator->Rest() = compiler->gtNewArgList(hiddenArgument); + } + + //------------------------------------------------------------------------ // RemoveOldStatement: remove original stmt from current block. // void RemoveOldStatement() -- 2.7.4