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