-
Notifications
You must be signed in to change notification settings - Fork 215
Merge requiresunsafe-corelib2 into feature/requires-unsafe #3209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feature/requires-unsafe
Are you sure you want to change the base?
Changes from 5 commits
f831e85
41893f5
73b3389
8aec308
f2e66af
9a8c31b
bc538f8
c0df804
b73ffce
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -401,7 +401,12 @@ internal IEnumerator<T> GetEnumerator<T>() | |
| { | ||
| // ! Warning: "this" is an array, not an SZArrayHelper. See comments above | ||
| // ! or you may introduce a security hole! | ||
| T[] @this = Unsafe.As<T[]>(this); | ||
| T[] @this; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
|
||
| unsafe | ||
| { | ||
| @this = Unsafe.As<T[]>(this); | ||
| } | ||
| int length = @this.Length; | ||
| return length == 0 ? SZGenericArrayEnumerator<T>.Empty : new SZGenericArrayEnumerator<T>(@this, length); | ||
| } | ||
|
|
@@ -411,23 +416,38 @@ private void CopyTo<T>(T[] array, int index) | |
| // ! Warning: "this" is an array, not an SZArrayHelper. See comments above | ||
| // ! or you may introduce a security hole! | ||
|
|
||
| T[] @this = Unsafe.As<T[]>(this); | ||
| T[] @this; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| @this = Unsafe.As<T[]>(this); | ||
| } | ||
| Array.Copy(@this, 0, array, index, @this.Length); | ||
| } | ||
|
|
||
| internal int get_Count<T>() | ||
| { | ||
| // ! Warning: "this" is an array, not an SZArrayHelper. See comments above | ||
| // ! or you may introduce a security hole! | ||
| T[] @this = Unsafe.As<T[]>(this); | ||
| T[] @this; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| @this = Unsafe.As<T[]>(this); | ||
| } | ||
| return @this.Length; | ||
| } | ||
|
|
||
| internal T get_Item<T>(int index) | ||
| { | ||
| // ! Warning: "this" is an array, not an SZArrayHelper. See comments above | ||
| // ! or you may introduce a security hole! | ||
| T[] @this = Unsafe.As<T[]>(this); | ||
| T[] @this; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| @this = Unsafe.As<T[]>(this); | ||
| } | ||
| if ((uint)index >= (uint)@this.Length) | ||
| { | ||
| ThrowHelper.ThrowArgumentOutOfRange_IndexMustBeLessException(); | ||
|
|
@@ -440,7 +460,12 @@ internal void set_Item<T>(int index, T value) | |
| { | ||
| // ! Warning: "this" is an array, not an SZArrayHelper. See comments above | ||
| // ! or you may introduce a security hole! | ||
| T[] @this = Unsafe.As<T[]>(this); | ||
| T[] @this; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| @this = Unsafe.As<T[]>(this); | ||
| } | ||
| if ((uint)index >= (uint)@this.Length) | ||
| { | ||
| ThrowHelper.ThrowArgumentOutOfRange_IndexMustBeLessException(); | ||
|
|
@@ -459,7 +484,12 @@ private bool Contains<T>(T value) | |
| { | ||
| // ! Warning: "this" is an array, not an SZArrayHelper. See comments above | ||
| // ! or you may introduce a security hole! | ||
| T[] @this = Unsafe.As<T[]>(this); | ||
| T[] @this; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| @this = Unsafe.As<T[]>(this); | ||
| } | ||
| return Array.IndexOf(@this, value, 0, @this.Length) >= 0; | ||
| } | ||
|
|
||
|
|
@@ -480,7 +510,12 @@ private int IndexOf<T>(T value) | |
| { | ||
| // ! Warning: "this" is an array, not an SZArrayHelper. See comments above | ||
| // ! or you may introduce a security hole! | ||
| T[] @this = Unsafe.As<T[]>(this); | ||
| T[] @this; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| @this = Unsafe.As<T[]>(this); | ||
| } | ||
| return Array.IndexOf(@this, value, 0, @this.Length); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,7 +55,12 @@ public sealed override bool Equals([NotNullWhen(true)] object? obj) | |
| // the types are the same, obj should also be a | ||
| // MulticastDelegate | ||
| Debug.Assert(obj is MulticastDelegate, "Shouldn't have failed here since we already checked the types are the same!"); | ||
| MulticastDelegate d = Unsafe.As<MulticastDelegate>(obj); | ||
| MulticastDelegate d; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
|
||
| unsafe | ||
| { | ||
| d = Unsafe.As<MulticastDelegate>(obj); | ||
| } | ||
|
|
||
| if (_invocationCount != 0) | ||
| { | ||
|
|
@@ -168,7 +173,11 @@ private static bool TrySetSlot(object?[] a, int index, object o) | |
| private unsafe MulticastDelegate NewMulticastDelegate(object[] invocationList, int invocationCount, bool thisIsMultiCastAlready) | ||
|
||
| { | ||
| // First, allocate a new multicast delegate just like this one, i.e. same type as the this object | ||
| MulticastDelegate result = Unsafe.As<MulticastDelegate>(RuntimeTypeHandle.InternalAllocNoChecks(RuntimeHelpers.GetMethodTable(this))); | ||
| MulticastDelegate result; | ||
| unsafe | ||
| { | ||
| result = Unsafe.As<MulticastDelegate>(RuntimeTypeHandle.InternalAllocNoChecks(RuntimeHelpers.GetMethodTable(this))); | ||
| } | ||
|
|
||
| // Performance optimization - if this already points to a true multicast delegate, | ||
| // copy _methodPtr and _methodPtrAux fields rather than calling into the EE to get them | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -60,7 +60,10 @@ public override T[] Rent(int minimumLength) | |
| SharedArrayPoolThreadLocalArray[]? tlsBuckets = t_tlsBuckets; | ||
| if (tlsBuckets is not null && (uint)bucketIndex < (uint)tlsBuckets.Length) | ||
| { | ||
| buffer = Unsafe.As<T[]>(tlsBuckets[bucketIndex].Array); | ||
agocke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| unsafe | ||
| { | ||
| buffer = Unsafe.As<T[]>(tlsBuckets[bucketIndex].Array); | ||
agocke marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| } | ||
| if (buffer is not null) | ||
| { | ||
| tlsBuckets[bucketIndex].Array = null; | ||
|
|
@@ -79,7 +82,10 @@ public override T[] Rent(int minimumLength) | |
| SharedArrayPoolPartitions? b = perCoreBuckets[bucketIndex]; | ||
| if (b is not null) | ||
| { | ||
| buffer = Unsafe.As<T[]>(b.TryPop()); | ||
| unsafe | ||
| { | ||
| buffer = Unsafe.As<T[]>(b.TryPop()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TryPop must always be a
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in commit c0df804. Made TryPush method unsafe with comment "Array parameter must be a T[]".
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please mark the TryPush method RequiresUnsafe instead.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in commit b73ffce. Changed TryPush method from |
||
| } | ||
| if (buffer is not null) | ||
| { | ||
| if (log.IsEnabled()) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -78,7 +78,19 @@ public abstract partial class Delegate : ICloneable, ISerializable | |
| /// Gets a value that indicates whether the <see cref="Delegate"/> has a single invocation target. | ||
| /// </summary> | ||
| /// <value>true if the <see cref="Delegate"/> has a single invocation target.</value> | ||
| public bool HasSingleTarget => Unsafe.As<MulticastDelegate>(this).HasSingleTarget; | ||
| public bool HasSingleTarget | ||
| { | ||
| get | ||
| { | ||
| MulticastDelegate md; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| md = Unsafe.As<MulticastDelegate>(this); | ||
| } | ||
| return md.HasSingleTarget; | ||
| } | ||
| } | ||
| #endif | ||
|
|
||
| /// <summary> | ||
|
|
@@ -94,7 +106,15 @@ public abstract partial class Delegate : ICloneable, ISerializable | |
| /// The method returns an empty enumerator for null delegate. | ||
| /// </remarks> | ||
| public static System.Delegate.InvocationListEnumerator<TDelegate> EnumerateInvocationList<TDelegate>(TDelegate? d) where TDelegate : System.Delegate | ||
| => new InvocationListEnumerator<TDelegate>(Unsafe.As<MulticastDelegate>(d)); | ||
| { | ||
| MulticastDelegate? md; | ||
| // FIXME: review unsafe to confirm correct annotation | ||
| unsafe | ||
| { | ||
| md = Unsafe.As<MulticastDelegate>(d); | ||
| } | ||
| return new InvocationListEnumerator<TDelegate>(md); | ||
| } | ||
|
|
||
| /// <summary> | ||
| /// Provides an enumerator for the invocation list of a delegate. | ||
|
|
@@ -128,9 +148,15 @@ public TDelegate Current | |
| public bool MoveNext() | ||
| { | ||
| int index = _index + 1; | ||
| if ((_current = Unsafe.As<TDelegate>(_delegate?.TryGetAt(index))) == null) | ||
| unsafe | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please add
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done in commit b73ffce. Added the FIXME comment and removed nested unsafe block. |
||
| { | ||
| return false; | ||
| unsafe | ||
| { | ||
| if ((_current = Unsafe.As<TDelegate>(_delegate?.TryGetAt(index))) == null) | ||
| { | ||
| return false; | ||
| } | ||
| } | ||
| } | ||
| _index = index; | ||
| return true; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| namespace System.Diagnostics.CodeAnalysis | ||
| { | ||
| /// <summary> | ||
| /// Indicates that the specified method requires dynamic access to code that is not referenced | ||
| /// statically, for example through <see cref="Reflection"/>. | ||
| /// </summary> | ||
| /// <remarks> | ||
| /// This allows tools to understand which methods are unsafe to call when removing unreferenced | ||
| /// code from an application. | ||
| /// </remarks> | ||
| [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)] | ||
|
||
| internal sealed class RequiresUnsafeAttribute : Attribute | ||
| { | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.