Skip to content

Commit 065a219

Browse files
committed
Fix compilation on netstandard
1 parent 60809c8 commit 065a219

File tree

9 files changed

+71
-35
lines changed

9 files changed

+71
-35
lines changed

src/Framework/Framework/Binding/DotvvmCapabilityProperty.CodeGeneration.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,16 @@ public static (LambdaExpression getter, LambdaExpression setter) CreatePropertyG
7676
var valueParameter = Expression.Parameter(type, "value");
7777
var ctor = typeof(VirtualPropertyGroupDictionary<>)
7878
.MakeGenericType(propType)
79-
.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, [ typeof(DotvvmBindableObject), typeof(ushort), typeof(bool) ])!;
79+
.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, [ typeof(DotvvmBindableObject), typeof(ushort), typeof(bool) ], null)!;
8080
var createMethod = typeof(VirtualPropertyGroupDictionary<>)
8181
.MakeGenericType(propType)
8282
.GetMethod(
8383
typeof(ValueOrBinding).IsAssignableFrom(elementType) ? nameof(VirtualPropertyGroupDictionary<int>.CreatePropertyDictionary) :
8484
nameof(VirtualPropertyGroupDictionary<int>.CreateValueDictionary),
8585
BindingFlags.NonPublic | BindingFlags.Static,
86-
[ typeof(DotvvmBindableObject), typeof(ushort) ]
86+
binder: null,
87+
[ typeof(DotvvmBindableObject), typeof(ushort) ],
88+
modifiers: null
8789
)!;
8890
var enumerableType = typeof(IEnumerable<>).MakeGenericType(typeof(KeyValuePair<,>).MakeGenericType(typeof(string), elementType));
8991
var copyFromMethod =

src/Framework/Framework/Binding/DotvvmPropertyIdAssignment.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,8 @@ public static ushort RegisterType(Type type)
217217
[MethodImpl(MethodImplOptions.NoInlining)]
218218
static ushort unlikely(Type type)
219219
{
220-
var types = MemoryMarshal.CreateReadOnlySpan(ref type, 1);
221220
Span<ushort> ids = stackalloc ushort[1];
222-
RegisterTypes(types, ids);
221+
RegisterTypes([type], ids);
223222
return ids[0];
224223
}
225224
}
@@ -420,7 +419,7 @@ private static void VolatileResize<T>(ref T[] array, int newSize)
420419
#region Group members
421420
public static ushort GetGroupMemberId(string name, bool registerIfNotFound)
422421
{
423-
var id = GroupMembers.TryGetId(name);
422+
var id = GroupMembers.TryGetId(name.AsSpan());
424423
if (id != 0)
425424
return id;
426425
if (propertyGroupMemberIds.TryGetValue(name, out id))

src/Framework/Framework/Compilation/ControlTree/DefaultControlResolver.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,14 @@ private List<Assembly> OrderAndFilterAssemblies(IEnumerable<Assembly> assemblies
108108
{
109109
if (name.Name is null)
110110
namelessAssemblies.Add(a);
111+
#if DotNetCore
111112
else if (renumbering.TryAdd(name.Name, assemblyList.Count))
112113
{
114+
#else
115+
else if (!renumbering.ContainsKey(name.Name))
116+
{
117+
renumbering.Add(name.Name, assemblyList.Count);
118+
#endif
113119
assemblyList.Add(a);
114120
references.Add(r);
115121
}

src/Framework/Framework/Controls/DotvvmControlProperties.cs

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal struct DotvvmControlProperties : IEnumerable<KeyValuePair<DotvvmPropert
2020
{
2121
// There are 3 possible states of this structure:
2222
// 1. Empty -> keys == values == null
23-
// 2. Dictinary -> keys == null & values is Dictionary<DotvvmPropertyId, object> --> it falls back to traditional mutable property dictionary
23+
// 2. Dictionary -> keys == null & values is Dictionary<DotvvmPropertyId, object> --> it falls back to traditional mutable property dictionary
2424
// 3. Array8 or Array16 -> keys is DotvvmPropertyId[] & values is object[] -- small linear search array
2525

2626
// Note about unsafe code:
@@ -118,7 +118,7 @@ private readonly void CheckInvariant()
118118
}
119119
}
120120
break;
121-
case TableState.Dictinary:
121+
case TableState.Dictionary:
122122
Debug.Assert(keys is null);
123123
Debug.Assert(values is Dictionary<DotvvmPropertyId, object>);
124124
break;
@@ -160,8 +160,8 @@ public void AssignBulk(DotvvmPropertyId[] keys, object?[] values, bool ownsKeys,
160160
[DoesNotReturn, MethodImpl(NoInlining)]
161161
void throwArgumentError(DotvvmPropertyId[]? keys, object?[]? values)
162162
{
163-
ThrowHelpers.ArgumentNull(nameof(keys));
164-
ThrowHelpers.ArgumentNull(nameof(values));
163+
ThrowHelpers.ArgumentNull(keys);
164+
ThrowHelpers.ArgumentNull(values);
165165
if (keys.Length is not 8 and not 16)
166166
throw new ArgumentException($"The length of keys array must be 8 or 16.", nameof(keys));
167167
if (keys.Length != values.Length)
@@ -183,15 +183,20 @@ public void AssignBulk(Dictionary<DotvvmPropertyId, object?> values, bool owns)
183183
this.keys = null;
184184
this.valuesAsDictionary = values;
185185
this.ownsValues = owns;
186-
this.state = TableState.Dictinary;
186+
this.state = TableState.Dictionary;
187187
}
188188
else
189189
{
190-
if (owns)
190+
if (owns && values.Count >= 8)
191191
{
192192
foreach (var (k, v) in this)
193193
{
194+
#if DotNetCore
194195
values.TryAdd(k, v);
196+
#else
197+
if (!values.ContainsKey(k))
198+
values[k] = v;
199+
#endif
195200
}
196201
this.values = values;
197202
this.keys = null;
@@ -236,7 +241,7 @@ private readonly bool ContainsOutlined(DotvvmPropertyId p) // doesn't need to be
236241
{
237242
return Impl.ContainsKey16(this.keys!, p);
238243
}
239-
if (state == TableState.Dictinary)
244+
if (state == TableState.Dictionary)
240245
{
241246
return valuesAsDictionary!.ContainsKey(p);
242247
}
@@ -295,7 +300,7 @@ private readonly int CountPropertyGroupOutlined(ushort groupId)
295300
return 0;
296301
case TableState.Array16:
297302
return Impl.CountPropertyGroup(this.keys!, groupId);
298-
case TableState.Dictinary:
303+
case TableState.Dictionary:
299304
{
300305
int count = 0;
301306
foreach (var key in valuesAsDictionary.Keys)
@@ -314,23 +319,25 @@ public void ClearPropertyGroup(ushort groupId)
314319
{
315320
if (state == TableState.Empty)
316321
return;
317-
else if (state == TableState.Dictinary)
322+
else if (state == TableState.Dictionary)
318323
{
319324
ClearPropertyGroupOutlined(groupId);
320325
return;
321326
}
322-
327+
323328
Debug.Assert(state is TableState.Array16 or TableState.Array8);
329+
#if Vectorize
324330
var bitmap = Impl.FindGroupBitmap(this.keys!, groupId);
325331
if (bitmap == 0)
326332
return;
327333

328334
OwnKeys();
329335
OwnValues();
336+
Impl.Assert(this.keys!.Length == this.valuesAsArray.Length);
330337

331338
int index = 0;
332-
var values = Impl.UnsafeArrayReference(this.valuesAsArray);
333-
var keys = Impl.UnsafeArrayReference(this.keys!);
339+
ref var values = ref Impl.UnsafeArrayReference(this.valuesAsArray);
340+
ref var keys = ref Impl.UnsafeArrayReference(this.keys);
334341
do
335342
{
336343
int bit = BitOperations.TrailingZeroCount(bitmap);
@@ -341,6 +348,21 @@ public void ClearPropertyGroup(ushort groupId)
341348
Unsafe.Add(ref values, index) = null;
342349
index++;
343350
} while (bitmap != 0);
351+
#else
352+
var keys = this.keys!;
353+
for (var i = 0; i < keys.Length; i++)
354+
{
355+
if (keys[i].IsInPropertyGroup(groupId))
356+
{
357+
if (!ownsKeys)
358+
keys = CloneKeys();
359+
if (!ownsValues)
360+
CloneValues();
361+
keys[i] = default;
362+
this.valuesAsArray[i] = null;
363+
}
364+
}
365+
#endif
344366
CheckInvariant();
345367
}
346368

@@ -398,7 +420,7 @@ public readonly bool TryGet(DotvvmPropertyId p, out object? value)
398420
if (index >= 0)
399421
{
400422
#if NET6_0_OR_GREATER
401-
value = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(valuesAsArrayUnsafe), index);
423+
value = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(valuesAsArrayUnsafe!), index);
402424
#else
403425
value = valuesAsArrayUnsafe![index];
404426
#endif
@@ -426,7 +448,7 @@ private readonly bool TryGetOutlined(DotvvmPropertyId p, out object? value)
426448
{
427449

428450
#if NET6_0_OR_GREATER
429-
value = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(valuesAsArrayUnsafe), index);
451+
value = Unsafe.Add(ref MemoryMarshal.GetArrayDataReference(valuesAsArrayUnsafe!), index);
430452
#else
431453
value = valuesAsArrayUnsafe![index];
432454
#endif
@@ -438,7 +460,7 @@ private readonly bool TryGetOutlined(DotvvmPropertyId p, out object? value)
438460
return false;
439461
}
440462
}
441-
case TableState.Dictinary:
463+
case TableState.Dictionary:
442464
return valuesAsDictionary.TryGetValue(p, out value);
443465
default:
444466
value = null;
@@ -740,9 +762,6 @@ public readonly int Count()
740762
return Impl.Count(this.keys);
741763
}
742764

743-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
744-
private static byte BoolToInt(bool x) => Unsafe.As<bool, byte>(ref x);
745-
746765
internal void CloneInto(ref DotvvmControlProperties newDict, DotvvmBindableObject newParent)
747766
{
748767
CheckInvariant();
@@ -886,7 +905,7 @@ void IncreaseSize()
886905
case TableState.Array16:
887906
SwitchToDictionary();
888907
break;
889-
case TableState.Dictinary:
908+
case TableState.Dictionary:
890909
break;
891910
default:
892911
Impl.Fail();
@@ -912,17 +931,17 @@ void SwitchToDictionary()
912931
if (keysTmp[i].Id != 0)
913932
d[keysTmp[i]] = valuesTmp[i];
914933
}
915-
this.state = TableState.Dictinary;
934+
this.state = TableState.Dictionary;
916935
this.valuesAsDictionary = d;
917936
this.keys = null;
918937
this.ownsValues = true;
919938
break;
920939
case TableState.Empty:
921-
this.state = TableState.Dictinary;
940+
this.state = TableState.Dictionary;
922941
this.valuesAsDictionary = new Dictionary<DotvvmPropertyId, object?>();
923942
this.ownsValues = true;
924943
break;
925-
case TableState.Dictinary:
944+
case TableState.Dictionary:
926945
break;
927946
default:
928947
Impl.Fail();
@@ -988,7 +1007,7 @@ public PropertyGroupEnumerable(in DotvvmControlProperties properties, ushort gro
9881007
public enum TableState : byte
9891008
{
9901009
Empty = 0,
991-
Dictinary = 1,
1010+
Dictionary = 1,
9921011
Array8 = 2,
9931012
Array16 = 3,
9941013
}

src/Framework/Framework/Controls/PropertyImmutableHashtable.cs renamed to src/Framework/Framework/Controls/PropertyDictionaryImpl.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,8 +357,8 @@ public static int Count(DotvvmPropertyId[] keys)
357357
Debug.Assert(keys.Length % 8 == 0);
358358
Debug.Assert(keys.Length >= AdhocTableSize);
359359

360-
#if Vectorize
361360
int count = 0;
361+
#if Vectorize
362362
ref var keysRef = ref MemoryMarshal.GetArrayDataReference(keys);
363363

364364
Debug.Assert(keys.Length % Vector256<uint>.Count == 0);
@@ -375,7 +375,7 @@ public static int Count(DotvvmPropertyId[] keys)
375375
#endif
376376
for (int i = 0; i < keys.Length; i++)
377377
{
378-
count += BoolToInt(keys[i].Id == 0);
378+
count += BoolToInt(keys[i].Id != 0);
379379
}
380380
return count;
381381
}
@@ -481,6 +481,16 @@ public static void Assert([DoesNotReturnIf(false)] bool condition)
481481
Fail();
482482
}
483483

484+
// #if !NETSTANDARD1_5_OR_GREATER
485+
// [MethodImpl(Inline)]
486+
// public static int TrailingZeroCount(uint v)
487+
// {
488+
// // https://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightFloatCast
489+
// float f = (float)(v & -v); // cast the least significant bit in v to a float
490+
// return (int)(Unsafe.As<float, uint>(ref f) >> 23) - 0x7f;
491+
// }
492+
// #endif
493+
484494
[DoesNotReturn]
485495
[MethodImpl(NoInlining)]
486496
public static void Fail() => Fail<object>();

src/Framework/Framework/Runtime/Commands/EventValidator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using DotVVM.Framework.Binding.Expressions;
77
using DotVVM.Framework.Controls;
88
using DotVVM.Framework.Hosting;
9+
using DotVVM.Framework.Utils;
910

1011
namespace DotVVM.Framework.Runtime.Commands
1112
{

src/Framework/Framework/Utils/FunctionalExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,13 @@ public static IEnumerable<T> SelectRecursively<T>(this IEnumerable<T> enumerable
8282
public static string StringJoin(this IEnumerable<string?> enumerable, string separator) =>
8383
string.Join(separator, enumerable);
8484

85+
#if !DotNetCore
8586
public static void Deconstruct<K, V>(this KeyValuePair<K, V> pair, out K key, out V value)
8687
{
8788
key = pair.Key;
8889
value = pair.Value;
8990
}
91+
#endif
9092
public static IEnumerable<(int, T)> Indexed<T>(this IEnumerable<T> enumerable) =>
9193
enumerable.Select((a, b) => (b, a));
9294

src/Tests/Runtime/CapabilityPropertyTests.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
43
using System.Linq;
54
using DotVVM.Framework.Binding;
65
using DotVVM.Framework.Binding.Expressions;
76
using DotVVM.Framework.Compilation.ControlTree;
87
using DotVVM.Framework.Controls;
9-
using DotVVM.Framework.ResourceManagement;
108
using DotVVM.Framework.Testing;
11-
using Microsoft.AspNetCore.Builder;
129
using Microsoft.Extensions.DependencyInjection;
1310
using Microsoft.VisualStudio.TestTools.UnitTesting;
1411

src/Tests/Runtime/DotvvmPropertyTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,13 @@
1010
using DotVVM.Framework.Controls;
1111
using DotVVM.Framework.Testing;
1212
using DotVVM.Framework.Utils;
13-
using Microsoft.AspNetCore.Components.Web.Virtualization;
1413
using Microsoft.Extensions.DependencyInjection;
1514
using Microsoft.VisualStudio.TestTools.UnitTesting;
1615
using System;
1716
using System.Collections.Concurrent;
1817
using System.Collections.Generic;
18+
using System.Diagnostics;
1919
using System.Linq;
20-
using System.Net.Sockets;
2120
using System.Reflection;
2221
using System.Threading;
2322
using System.Threading.Tasks;
@@ -476,6 +475,7 @@ public void DotvvmProperty_VirtualDictionary_Append(int testClone)
476475
}
477476

478477
[TestMethod, Ignore]
478+
[Conditional("NET6_0_OR_GREATER")]
479479
public void DotvvmProperty_ParallelAccess_DoesntCrashProcess()
480480
{
481481
var properties = new DotvvmProperty[] {

0 commit comments

Comments
 (0)