Skip to content

Commit

Permalink
Patches for scoped locals
Browse files Browse the repository at this point in the history
dotnet/roslyn#64093

This change enforced that `scoped` on a local set the escape scope to
the current block where previously it was incorrectly setting to the
containing method.
  • Loading branch information
cston authored and jaredpar committed Sep 30, 2022
1 parent 16c0c21 commit 4b8b2ff
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,9 @@ public override MethodImplAttributes GetMethodImplementationFlags()
Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, 1);

StackAllocatedByRefs byrefStorage = default;
#pragma warning disable 8500
IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
#pragma warning restore 8500

CheckArguments(
copyOfParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -235,11 +235,15 @@ public DynamicInvokeInfo(MethodBase method, IntPtr invokeThunk)
StackAllocedArguments argStorage = default;
StackAllocatedByRefs byrefStorage = default;

#pragma warning disable 8500
CheckArguments(ref argStorage._arg0!, (ByReference*)&byrefStorage, parameters, binderBundle);
#pragma warning restore 8500

try
{
#pragma warning disable 8500
ret = ref RawCalliHelper.Call(InvokeThunk, (void*)methodToCall, ref thisArg, ref ret, &byrefStorage);
#pragma warning restore 8500
DebugAnnotations.PreviousCallContainsDebuggerStepInCode();
}
catch (Exception e) when (wrapInTargetInvocationException)
Expand Down Expand Up @@ -268,7 +272,9 @@ private unsafe ref byte InvokeWithManyArguments(
IntPtr* pStorage = stackalloc IntPtr[2 * argCount];
NativeMemory.Clear(pStorage, (nuint)(2 * argCount) * (nuint)sizeof(IntPtr));

ByReference* pByRefStorage = (ByReference*)(pStorage + argCount);
#pragma warning disable 8500
void* pByRefStorage = (ByReference*)(pStorage + argCount);
#pragma warning restore 8500

RuntimeImports.GCFrameRegistration regArgStorage = new(pStorage, (uint)argCount, areByRefs: false);
RuntimeImports.GCFrameRegistration regByRefStorage = new(pByRefStorage, (uint)argCount, areByRefs: true);
Expand Down Expand Up @@ -326,7 +332,7 @@ private unsafe ref byte InvokeWithManyArguments(

private unsafe void CheckArguments(
ref object copyOfParameters,
ByReference* byrefParameters,
void* byrefParameters,
object?[] parameters,
BinderBundle binderBundle)
{
Expand Down Expand Up @@ -398,8 +404,10 @@ private unsafe void CheckArguments(

Unsafe.Add(ref copyOfParameters, i) = arg!;

byrefParameters[i] = new ByReference(ref (argumentInfo.Transform & Transform.Reference) != 0 ?
#pragma warning disable 8500
((ByReference*)byrefParameters)[i] = new ByReference(ref (argumentInfo.Transform & Transform.Reference) != 0 ?
ref Unsafe.As<object, byte>(ref Unsafe.Add(ref copyOfParameters, i)) : ref arg.GetRawData());
#pragma warning restore 8500
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ BindingFlags invokeAttr
shouldCopyBack[i] = copyBackArg;
copyOfParameters[i] = arg;

#pragma warning disable 8500
if (isValueType)
{
#if !MONO // Temporary until Mono is updated.
Expand All @@ -254,6 +255,7 @@ BindingFlags invokeAttr
ByReference objRef = ByReference.Create(ref copyOfParameters[i]);
*(ByReference*)(byrefParameters + i) = objRef;
}
#pragma warning restore 8500
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,9 @@ internal void ThrowNoInvokeException()
Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);

StackAllocatedByRefs byrefStorage = default;
#pragma warning disable 8500
IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
#pragma warning restore 8500

CheckArguments(
copyOfParameters,
Expand Down Expand Up @@ -299,7 +301,9 @@ public override object Invoke(BindingFlags invokeAttr, Binder? binder, object?[]
Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);

StackAllocatedByRefs byrefStorage = default;
#pragma warning disable 8500
IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
#pragma warning restore 8500

CheckArguments(
copyOfParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ private void ThrowNoInvokeException()
Span<ParameterCopyBackAction> shouldCopyBackParameters = new(ref argStorage._copyBack0, argCount);

StackAllocatedByRefs byrefStorage = default;
#pragma warning disable 8500
IntPtr* pByRefStorage = (IntPtr*)&byrefStorage;
#pragma warning restore 8500

CheckArguments(
copyOfParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal static partial class JsonHelpers
/// Returns the span for the given reader.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ReadOnlySpan<byte> GetSpan(this ref Utf8JsonReader reader)
public static ReadOnlySpan<byte> GetSpan(this scoped ref Utf8JsonReader reader)
{
return reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ private void WriteStringEscapeProperty(scoped ReadOnlySpan<char> propertyName, i
Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= propertyName.Length);

char[]? propertyArray = null;
scoped Span<char> escapedPropertyName;

if (firstEscapeIndexProp != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);

scoped Span<char> escapedPropertyName;
if (length > JsonConstants.StackallocCharThreshold)
{
propertyArray = ArrayPool<char>.Shared.Rent(length);
Expand Down Expand Up @@ -269,12 +269,12 @@ private void WriteStringEscapeProperty(scoped ReadOnlySpan<byte> utf8PropertyNam
Debug.Assert(int.MaxValue / JsonConstants.MaxExpansionFactorWhileEscaping >= utf8PropertyName.Length);

byte[]? propertyArray = null;
scoped Span<byte> escapedPropertyName;

if (firstEscapeIndexProp != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp);

scoped Span<byte> escapedPropertyName;
if (length > JsonConstants.StackallocByteThreshold)
{
propertyArray = ArrayPool<byte>.Shared.Rent(length);
Expand Down Expand Up @@ -1076,12 +1076,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<char> property

char[]? valueArray = null;
char[]? propertyArray = null;
scoped Span<char> escapedValue;

if (firstEscapeIndexVal != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal);

scoped Span<char> escapedValue;
if (length > JsonConstants.StackallocCharThreshold)
{
valueArray = ArrayPool<char>.Shared.Rent(length);
Expand All @@ -1096,11 +1096,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<char> property
value = escapedValue.Slice(0, written);
}

scoped Span<char> escapedPropertyName;

if (firstEscapeIndexProp != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);

scoped Span<char> escapedPropertyName;
if (length > JsonConstants.StackallocCharThreshold)
{
propertyArray = ArrayPool<char>.Shared.Rent(length);
Expand Down Expand Up @@ -1135,12 +1136,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<byte> utf8Prop

byte[]? valueArray = null;
byte[]? propertyArray = null;
scoped Span<byte> escapedValue;

if (firstEscapeIndexVal != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal);

scoped Span<byte> escapedValue;
if (length > JsonConstants.StackallocByteThreshold)
{
valueArray = ArrayPool<byte>.Shared.Rent(length);
Expand All @@ -1155,11 +1156,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<byte> utf8Prop
utf8Value = escapedValue.Slice(0, written);
}

scoped Span<byte> escapedPropertyName;

if (firstEscapeIndexProp != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp);

scoped Span<byte> escapedPropertyName;
if (length > JsonConstants.StackallocByteThreshold)
{
propertyArray = ArrayPool<byte>.Shared.Rent(length);
Expand Down Expand Up @@ -1194,12 +1196,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<char> property

byte[]? valueArray = null;
char[]? propertyArray = null;
scoped Span<byte> escapedValue;

if (firstEscapeIndexVal != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(utf8Value.Length, firstEscapeIndexVal);

scoped Span<byte> escapedValue;
if (length > JsonConstants.StackallocByteThreshold)
{
valueArray = ArrayPool<byte>.Shared.Rent(length);
Expand All @@ -1214,11 +1216,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<char> property
utf8Value = escapedValue.Slice(0, written);
}

scoped Span<char> escapedPropertyName;

if (firstEscapeIndexProp != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(propertyName.Length, firstEscapeIndexProp);

scoped Span<char> escapedPropertyName;
if (length > JsonConstants.StackallocCharThreshold)
{
propertyArray = ArrayPool<char>.Shared.Rent(length);
Expand Down Expand Up @@ -1253,12 +1256,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<byte> utf8Prop

char[]? valueArray = null;
byte[]? propertyArray = null;
scoped Span<char> escapedValue;

if (firstEscapeIndexVal != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(value.Length, firstEscapeIndexVal);

scoped Span<char> escapedValue;
if (length > JsonConstants.StackallocCharThreshold)
{
valueArray = ArrayPool<char>.Shared.Rent(length);
Expand All @@ -1273,11 +1276,12 @@ private void WriteStringEscapePropertyOrValue(scoped ReadOnlySpan<byte> utf8Prop
value = escapedValue.Slice(0, written);
}

scoped Span<byte> escapedPropertyName;

if (firstEscapeIndexProp != -1)
{
int length = JsonWriterHelper.GetMaxEscapedLength(utf8PropertyName.Length, firstEscapeIndexProp);

scoped Span<byte> escapedPropertyName;
if (length > JsonConstants.StackallocByteThreshold)
{
propertyArray = ArrayPool<byte>.Shared.Rent(length);
Expand Down

0 comments on commit 4b8b2ff

Please sign in to comment.