Update IterActionGenerator to use ReferenceHandle

wip/source-generators
copygirl 1 year ago
parent ec62ad8115
commit 3d533fcee9
  1. 2
      src/gaemstone.ECS
  2. 28
      src/gaemstone/Utility/IL/IterActionGenerator.cs

@ -1 +1 @@
Subproject commit 619e2b24c6ff8797aed702a77954adfbd40f6f4d
Subproject commit 46e171940eea723f2ad8376b5056afd9b9d8a340

@ -6,7 +6,6 @@ using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using gaemstone.ECS;
using GCHandle = System.Runtime.InteropServices.GCHandle;
namespace gaemstone.Utility.IL;
@ -15,15 +14,14 @@ public unsafe class IterActionGenerator
{
private static readonly ConstructorInfo _entityRefCtor = typeof(EntityRef).GetConstructors().Single();
private static readonly PropertyInfo _iteratorWorldProp = typeof(Iterator).GetProperty(nameof(Iterator.World))!;
private static readonly PropertyInfo _iteratorDeltaTimeProp = typeof(Iterator).GetProperty(nameof(Iterator.DeltaTime))!;
private static readonly PropertyInfo _iteratorCountProp = typeof(Iterator).GetProperty(nameof(Iterator.Count))!;
private static readonly MethodInfo _iteratorEntityMethod = typeof(Iterator).GetMethod(nameof(Iterator.Entity))!;
private static readonly MethodInfo _iteratorFieldMethod = typeof(Iterator).GetMethod(nameof(Iterator.Field))!;
private static readonly PropertyInfo _iteratorWorldProp = typeof(Iterator).GetProperty(nameof(Iterator.World))!;
private static readonly PropertyInfo _iteratorDeltaTimeProp = typeof(Iterator).GetProperty(nameof(Iterator.DeltaTime))!;
private static readonly PropertyInfo _iteratorCountProp = typeof(Iterator).GetProperty(nameof(Iterator.Count))!;
private static readonly MethodInfo _iteratorEntityMethod = typeof(Iterator).GetMethod(nameof(Iterator.Entity))!;
private static readonly MethodInfo _iteratorFieldMethod = typeof(Iterator).GetMethod(nameof(Iterator.Field))!;
private static readonly MethodInfo _iteratorFieldOrEmptyMethod = typeof(Iterator).GetMethod(nameof(Iterator.FieldOrEmpty))!;
private static readonly MethodInfo _handleFromIntPtrMethod = typeof(GCHandle).GetMethod(nameof(GCHandle.FromIntPtr))!;
private static readonly PropertyInfo _handleTargetProp = typeof(GCHandle).GetProperty(nameof(GCHandle.Target))!;
private static readonly PropertyInfo _handleTargetProp = typeof(ReferenceHandle).GetProperty(nameof(ReferenceHandle.Target))!;
private static readonly ConditionalWeakTable<MethodInfo, IterActionGenerator> _cache = new();
private static readonly Dictionary<Type, Action<ILGeneratorWrapper, IArgument<Iterator>>> _globalUniqueParameters = new() {
@ -136,11 +134,11 @@ public unsafe class IterActionGenerator
paramData.Add((p, term, fieldLocal, tempLocal));
}
// If there's any reference type parameters, we need to define a GCHandle local.
// If there's any reference type parameters, we need to define a ReferenceHandle local.
var hasReferenceType = paramData
.Where(p => p.Info.Kind > ParamKind.Unique)
.Any(p => !p.Info.UnderlyingType.IsValueType);
var handleLocal = hasReferenceType ? IL.Local<GCHandle>() : null;
var handleLocal = hasReferenceType ? IL.Local<ReferenceHandle>() : null;
var indexLocal = IL.Local<int>("iter_index");
var countLocal = IL.Local<int>("iter_count");
@ -206,8 +204,7 @@ public unsafe class IterActionGenerator
IL.LoadObj(info.FieldType);
if (!isValueType) {
IL.Comment($"Convert nint to {paramName}");
IL.Call(_handleFromIntPtrMethod);
IL.Comment($"Convert ReferenceHandle to {paramName}");
IL.Store(handleLocal!);
IL.LoadAddr(handleLocal!);
IL.Call(_handleTargetProp.GetMethod!);
@ -225,8 +222,7 @@ public unsafe class IterActionGenerator
IL.Call(spanItemMethod);
IL.LoadObj(info.FieldType);
if (!isValueType) {
IL.Comment($"Convert nint to {paramName}");
IL.Call(_handleFromIntPtrMethod);
IL.Comment($"Convert ReferenceHandle to {paramName}");
IL.Store(handleLocal!);
IL.LoadAddr(handleLocal!);
IL.Call(_handleTargetProp.GetMethod!);
@ -278,8 +274,8 @@ public unsafe class IterActionGenerator
Kind = kind;
ParameterType = paramType;
UnderlyingType = underlyingType;
// Reference types have a backing type of nint - they're pointers.
FieldType = underlyingType.IsValueType ? underlyingType : typeof(nint);
// Reference types have a backing type of ReferenceHandle.
FieldType = underlyingType.IsValueType ? underlyingType : typeof(ReferenceHandle);
if (UnderlyingType.Has<SingletonAttribute>()) Source = UnderlyingType;
if (Info.Get<SourceAttribute>()?.Type is Type type) Source = type;

Loading…
Cancel
Save