From f0ff0d3630b2d1100aedc0b26a04f659341b9014 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 1 Mar 2022 10:37:13 -0800 Subject: [PATCH] Improved null handling in reflected method invocation --- BeefLibs/corlib/src/Reflection/MethodInfo.bf | 52 ++++++++++++++++++-- BeefLibs/corlib/src/System.bf | 15 ++++++ 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/BeefLibs/corlib/src/Reflection/MethodInfo.bf b/BeefLibs/corlib/src/Reflection/MethodInfo.bf index af81e65f..2b0dd4d4 100644 --- a/BeefLibs/corlib/src/Reflection/MethodInfo.bf +++ b/BeefLibs/corlib/src/Reflection/MethodInfo.bf @@ -595,13 +595,51 @@ namespace System.Reflection bool unbox = false; bool unboxToPtr = false; - let argType = arg.[Friend]RawGetType(); - void* dataPtr = (uint8*)Internal.UnsafeCastToPtr(arg) + argType.[Friend]mMemberDataOffset; + void* nullPtr = null; + + Type argType = null; + void* dataPtr = null; + bool isValid = true; - bool added = false; + bool handled = false; - if (var refParamType = paramType as RefType) + if (arg == null) + { + isValid = false; + + if ((paramType.IsPointer) || (paramType.IsObject) || (paramType.IsInterface)) + { + argType = paramType; + dataPtr = &nullPtr; + isValid = true; + } + else if (var genericType = paramType as SpecializedGenericType) + { + if (genericType.UnspecializedType == typeof(Nullable<>)) + { + argType = paramType; + dataPtr = ScopedAllocZero!(paramType.Size, 16); + isValid = true; + handled = true; + } + } + } + else + { + argType = arg.[Friend]RawGetType(); + dataPtr = (uint8*)Internal.UnsafeCastToPtr(arg) + argType.[Friend]mMemberDataOffset; + } + + if (!isValid) + { + // Not valid + } + else if (handled) + { + + } + else if (var refParamType = paramType as RefType) { if (argType.IsBoxedStructPtr || argType.IsBoxedPrimitivePtr) { @@ -633,7 +671,7 @@ namespace System.Reflection } else if (paramType.IsValueType) { - bool handled = true; + handled = true; if (!argType.IsBoxed) return .Err(.InvalidArgument((.)argIdx)); @@ -647,6 +685,10 @@ namespace System.Reflection dataPtr = *(void**)dataPtr; handled = true; } + else + { + isValid = underlyingType == paramType; + } if (!handled) { diff --git a/BeefLibs/corlib/src/System.bf b/BeefLibs/corlib/src/System.bf index 9289da0a..a2386735 100644 --- a/BeefLibs/corlib/src/System.bf +++ b/BeefLibs/corlib/src/System.bf @@ -273,4 +273,19 @@ static } data } + + public static mixin ScopedAllocZero(int size, int align) + { + void* data; + if (size <= 128) + { + data = scope:mixin [Align(align)] uint8[size]*; + } + else + { + data = new [Align(align)] uint8[size]*; + defer:mixin delete data; + } + data + } } \ No newline at end of file