Skip to content

Commit 2a5eca2

Browse files
committed
If setmethod func ptr is null then use direct reflection
1 parent 30f8f77 commit 2a5eca2

File tree

1 file changed

+28
-31
lines changed

1 file changed

+28
-31
lines changed

Runtime/Code/Luau/LuauCoreCallbacks.cs

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Linq.Expressions;
88
using System.Reflection;
99
using System.Reflection.Emit;
10+
using System.Runtime.CompilerServices;
1011
using System.Runtime.InteropServices;
1112
using System.Text;
1213
using System.Threading.Tasks;
@@ -60,6 +61,7 @@ private struct PropertyGetReflectionCache {
6061
[FormerlySerializedAs("pi")] public PropertyInfo propertyInfo;
6162
public Delegate GetProperty;
6263
public bool HasGetPropertyFunc;
64+
public bool IsNativeClass;
6365
}
6466

6567
// Hopefully faster dictionary comparison / hash time
@@ -627,41 +629,37 @@ private static int SetProperty(LuauContext context, IntPtr thread, int instanceI
627629

628630
private static Delegate CreateSetter<T>(PropertyInfo propertyInfo, bool isStatic) {
629631
var setMethod = propertyInfo.GetSetMethod();
632+
630633
var declaringType = propertyInfo.DeclaringType;
631-
632634
unsafe {
635+
var setPointer = setMethod
636+
.MethodHandle
637+
.GetFunctionPointer();
638+
639+
if (setPointer == IntPtr.Zero || declaringType.IsValueType) {
640+
// Just direct reflection for this case (like ParticleEmitter modules -- weird Unity niche)
641+
return new Action<object, T>((object target, T value) => { propertyInfo.SetValue(target, value); });
642+
}
643+
644+
633645
if (!isStatic) {
634-
if (declaringType.IsValueType) {
635-
// Just direct reflection for this case (like ParticleEmitter modules -- weird Unity niche)
636-
return new Action<object, T>((object target, T value) => {
637-
propertyInfo.SetValue(target, value);
638-
});
639-
} else {
640-
// Original class handling
641-
delegate*<object, T, void> funcPtr = (delegate*<object, T, void>)setMethod
642-
.MethodHandle
643-
.GetFunctionPointer()
644-
.ToPointer();
646+
// Original class handling
647+
delegate*<object, T, void> funcPtr = (delegate*<object, T, void>)setPointer.ToPointer();;
645648

646-
var setter = new Setter<T>((obj, val) => { funcPtr(obj, val); });
647-
return setter;
648-
}
649+
var setter = new Setter<T>((obj, val) => { funcPtr(obj, val); });
650+
return setter;
649651
} else {
650-
delegate*<T, void> funcPtr = (delegate*<T, void>)setMethod
651-
.MethodHandle
652-
.GetFunctionPointer()
653-
.ToPointer();
654-
652+
delegate*<T, void> funcPtr = (delegate*<T, void>)setPointer.ToPointer();;
655653
var setter = new StaticSetter<T>((val) => { funcPtr(val); });
656654
return setter;
657655
}
658656
}
659657
}
660658

661659
private static T GetValue<T>(object instance, PropertyGetReflectionCache cacheData) {
662-
// if (typeof(T) == typeof(object)) {
660+
if (typeof(T) == typeof(object) || cacheData.IsNativeClass) {
663661
return (T) cacheData.propertyInfo.GetMethod.Invoke(instance, null);
664-
// }
662+
}
665663

666664
if (!cacheData.HasGetPropertyFunc) {
667665
var getMethod = cacheData.propertyInfo.GetGetMethod();
@@ -689,24 +687,21 @@ private static T GetValue<T>(object instance, PropertyGetReflectionCache cacheDa
689687
}
690688

691689
private static void SetValue<T>(object instance, T value, PropertyInfo pi) {
692-
pi.SetValue(instance, value);
693-
return;
694-
695690
var staticSet = instance == null;
696691
if (!_propertySetterCache.TryGetValue((staticSet, pi.DeclaringType, pi.Name), out var setter)) {
697692
setter = CreateSetter<T>(pi, staticSet);
698693
_propertySetterCache[(staticSet, pi.DeclaringType, pi.Name)] = setter;
699694
}
700695

696+
if (pi.GetSetMethod().MethodHandle.GetFunctionPointer() == IntPtr.Zero || pi.DeclaringType.IsValueType) {
697+
((Action<object, T>)setter)(instance, value);
698+
return;
699+
}
700+
701701
if (staticSet) {
702702
((StaticSetter<T>) setter)(value);
703703
} else {
704-
if (pi.DeclaringType.IsValueType) {
705-
((Action<object, T>)setter)(instance, value);
706-
}
707-
else {
708-
((Setter<T>)setter)(instance, value);
709-
}
704+
((Setter<T>)setter)(instance, value);
710705
}
711706
}
712707

@@ -1682,6 +1677,8 @@ private static PropertyGetReflectionCache SetPropertyCacheValue(Type objectType,
16821677
var cacheData = new PropertyGetReflectionCache {
16831678
t = propertyInfo.PropertyType,
16841679
propertyInfo = propertyInfo,
1680+
IsNativeClass = propertyInfo.DeclaringType.GetCustomAttributes(false)
1681+
.Any(attr => attr.GetType().Name == "NativeClassAttribute")
16851682
};
16861683
LuauCore.propertyGetCache[new PropertyCacheKey(objectType, propName)] = cacheData;
16871684
return cacheData;

0 commit comments

Comments
 (0)