coreRT fat pointer hidden argument fix for calls with retBufArg
authorSergey Andreenko <seandree@microsoft.com>
Fri, 24 Feb 2017 21:39:36 +0000 (13:39 -0800)
committerSergey Andreenko <seandree@microsoft.com>
Tue, 28 Feb 2017 00:22:57 +0000 (16:22 -0800)
Commit migrated from https://github.com/dotnet/coreclr/commit/792ffd6ac53ac576bc6893185c2bcaa68c589fa8

src/coreclr/src/jit/flowgraph.cpp

index 97570c4..3749ba3 100644 (file)
@@ -24469,7 +24469,7 @@ private:
         //    fixedFptrAddress - pointer to the tuple <methodPointer, instantiationArgumentPointer>
         //
         // 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()