Skip to content

Commit

Permalink
use arrayhelpers to initialize newobj array (dotnet#5011)
Browse files Browse the repository at this point in the history
  • Loading branch information
tonerdo committed May 12, 2020
1 parent e080273 commit 0951632
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 38 deletions.
Expand Up @@ -25,6 +25,7 @@
using System.Runtime.CompilerServices;
using System.Threading;

using Internal.Runtime.CompilerHelpers;
using Internal.Runtime.CompilerServices;

#if TARGET_64BIT
Expand Down Expand Up @@ -161,6 +162,25 @@ public static unsafe Array NewMultiDimArray(RuntimeTypeHandle typeHandleForArray
return Array.NewMultiDimArray(typeHandleForArrayType.ToEETypePtr(), pLengths, lengths.Length);
}

//
// Helper to create an array from a newobj instruction
//
public static unsafe Array NewObjArray(RuntimeTypeHandle typeHandleForArrayType, int[] arguments)
{
EETypePtr eeTypePtr = typeHandleForArrayType.ToEETypePtr();
Debug.Assert(eeTypePtr.IsArray);

int nArguments = arguments.Length;
int* pArguments = stackalloc int[nArguments];

for (int i = 0; i < nArguments; i++)
{
pArguments[i] = arguments[i];
}

return ArrayHelpers.NewObjArray((IntPtr)eeTypePtr.ToPointer(), nArguments, pArguments);
}

public static ref byte GetSzArrayElementAddress(Array array, int index)
{
if ((uint)index >= (uint)array.Length)
Expand Down
Expand Up @@ -18,7 +18,7 @@ internal static class ArrayHelpers
/// Helper for array allocations via `newobj` IL instruction. Dimensions are passed in as block of integers.
/// The content of the dimensions block may be modified by the helper.
/// </summary>
private static unsafe Array NewObjArray(IntPtr pEEType, int nDimensions, int* pDimensions)
public static unsafe Array NewObjArray(IntPtr pEEType, int nDimensions, int* pDimensions)
{
EETypePtr eeType = new EETypePtr(pEEType);
Debug.Assert(eeType.IsArray);
Expand Down
Expand Up @@ -2657,7 +2657,7 @@ private void InterpretCall(int token)
_stack.Push(callInfo.ReturnValue);
}

private void InterpretNewObj(int token)
private unsafe void InterpretNewObj(int token)
{
MethodDesc method = (MethodDesc)_methodIL.GetObject(token);
MethodSignature signature = method.Signature;
Expand All @@ -2671,45 +2671,13 @@ private void InterpretNewObj(int token)

if (owningType.IsArray)
{
LowLevelList<int> lengths = default;
LowLevelList<int> lowerBounds = default;

ArrayType arrayType = owningType as ArrayType;
Debug.Assert(arrayType != null);

if (signature.Length == arrayType.Rank)
{
lengths = new LowLevelList<int>(signature.Length);
for (int i = arguments.Length - 1; i >= 0; i--)
{
lengths.Add(arguments[i].AsInt32());
}
}
else if (signature.Length > arrayType.Rank)
{
Debug.Assert(arrayType.Rank * 2 == signature.Length);

lengths = new LowLevelList<int>(arrayType.Rank);
lowerBounds = new LowLevelList<int>(arrayType.Rank);

for (int i = arguments.Length - 1; i >= 0; i--)
{
if (i % 2 == 1)
{
lowerBounds.Add(arguments[i].AsInt32());
}
else
{
lengths.Add(arguments[i].AsInt32());
}
}
}
else
LowLevelList<int> lArguments = new LowLevelList<int>(arguments.Length);
for (int i = arguments.Length - 1; i >= 0; i--)
{
ThrowHelper.ThrowInvalidProgramException();
lArguments.Add(arguments[i].AsInt32());
}

Array array = RuntimeAugments.NewMultiDimArray(owningType.GetRuntimeTypeHandle(), lengths?.ToArray(), lowerBounds?.ToArray());
Array array = RuntimeAugments.NewObjArray(owningType.GetRuntimeTypeHandle(), lArguments.ToArray());
_stack.Push(StackItem.FromObjectRef(array));
return;
}
Expand Down

0 comments on commit 0951632

Please sign in to comment.