[ObjCRuntime] Enable nullability in Runtime.CoreCLR.cs (#17114)

And fix the resulting build errors+warnings.
This commit is contained in:
Rolf Bjarne Kvinge 2023-01-09 10:44:32 +01:00 коммит произвёл GitHub
Родитель d1aaf8e1c0
Коммит d09d147718
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
1 изменённых файлов: 118 добавлений и 98 удалений

Просмотреть файл

@ -19,8 +19,11 @@
#if NET && !COREBUILD
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
@ -89,7 +92,7 @@ namespace ObjCRuntime {
// Define VERBOSE_LOG at the top of this file to get all printfs
[System.Diagnostics.Conditional ("VERBOSE_LOG")]
static void log_coreclr_render (string message, params object[] argumentsToRender)
static void log_coreclr_render (string message, params object?[] argumentsToRender)
{
var args = new string [argumentsToRender.Length];
for (var i = 0; i < args.Length; i++) {
@ -105,7 +108,7 @@ namespace ObjCRuntime {
// Don't call ToString on an INativeObject, we may end up with infinite recursion.
arg = $"{inativeobj.Handle.ToString ()} ({obj.GetType ()})";
} else {
var toString = obj.ToString ();
var toString = obj.ToString () ?? string.Empty;
// Print one line, and at most 256 characters.
var strLength = Math.Min (256, toString.Length);
var eol = toString.IndexOf ('\n');
@ -189,7 +192,7 @@ namespace ObjCRuntime {
static unsafe MonoObject* CreateException (ExceptionType type, IntPtr arg0)
{
Exception rv = null;
Exception rv;
var str0 = Marshal.PtrToStringAuto (arg0);
switch (type) {
@ -218,6 +221,9 @@ namespace ObjCRuntime {
var path = Marshal.PtrToStringAuto (assembly_name);
var name = Path.GetFileNameWithoutExtension (path);
if (path is null)
throw new ArgumentOutOfRangeException ($"Invalid assembly name pointer: 0x{assembly_name.ToString ("x")}");
log_coreclr ($"Runtime.FindAssembly (0x{assembly_name.ToString ("x")} = {name})");
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies ()) {
@ -231,7 +237,7 @@ namespace ObjCRuntime {
log_coreclr ($" Did not find the assembly in the app domain's loaded assemblies. Will try to load it.");
var loadedAssembly = Assembly.LoadFrom (path);
if (loadedAssembly != null) {
if (loadedAssembly is not null) {
log_coreclr ($" Loaded {loadedAssembly.GetName ().Name}");
return GetMonoObject (loadedAssembly);
}
@ -243,21 +249,24 @@ namespace ObjCRuntime {
static unsafe void SetPendingException (MonoObject* exception_obj)
{
var exc = (Exception) GetMonoObjectTarget (exception_obj);
var exc = (Exception?) GetMonoObjectTarget (exception_obj);
log_coreclr ($"Runtime.SetPendingException ({exc})");
ObjectiveCMarshal.SetMessageSendPendingException (exc);
}
unsafe static sbyte IsClassOfType (MonoObject *typeobj, TypeLookup match)
{
var rv = IsClassOfType ((Type) GetMonoObjectTarget (typeobj), match);
var rv = IsClassOfType ((Type?) GetMonoObjectTarget (typeobj), match);
return (sbyte) (rv ? 1 : 0);
}
static bool IsClassOfType (Type type, TypeLookup match)
static bool IsClassOfType (Type? type, TypeLookup match)
{
var rv = false;
if (type is null)
return false;
switch (match) {
case TypeLookup.System_Array:
rv = type.IsArray;
@ -297,7 +306,7 @@ namespace ObjCRuntime {
static unsafe MonoObject* LookupType (TypeLookup type)
{
Type rv = null;
Type rv;
switch (type) {
case TypeLookup.Foundation_NSNumber:
@ -320,13 +329,13 @@ namespace ObjCRuntime {
static unsafe MonoObject* GetElementClass (MonoObject* classobj)
{
var type = (Type) GetMonoObjectTarget (classobj);
return (MonoObject*) GetMonoObject (type.GetElementType ());
var type = (Type?) GetMonoObjectTarget (classobj);
return (MonoObject*) GetMonoObject (type?.GetElementType ());
}
static unsafe MonoObject* GetNullableElementType (MonoObject* typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
var elementType = type.GetGenericArguments () [0];
return (MonoObject*) GetMonoObject (elementType);
}
@ -334,7 +343,7 @@ namespace ObjCRuntime {
static IntPtr CreateGCHandle (IntPtr gchandle, GCHandleType type)
{
// It's valid to create a GCHandle to a null value.
object obj = null;
object? obj = null;
if (gchandle != IntPtr.Zero)
obj = GetGCHandleTarget (gchandle);
return AllocGCHandle (obj, type);
@ -355,9 +364,9 @@ namespace ObjCRuntime {
}
// Returns a retained MonoObject. Caller must release.
static IntPtr GetMonoObject (object obj)
static IntPtr GetMonoObject (object? obj)
{
if (obj == null)
if (obj is null)
return IntPtr.Zero;
return GetMonoObjectImpl (obj);
@ -387,12 +396,12 @@ namespace ObjCRuntime {
return rv;
}
static unsafe object GetMonoObjectTarget (MonoObject* mobj)
static unsafe object? GetMonoObjectTarget (MonoObject* mobj)
{
return GetMonoObjectTarget ((IntPtr) mobj);
}
static object GetMonoObjectTarget (MonoObjectPtr mobj)
static object? GetMonoObjectTarget (MonoObjectPtr mobj)
{
if (mobj == IntPtr.Zero)
return null;
@ -415,9 +424,9 @@ namespace ObjCRuntime {
return rv;
}
static void StructureToPtr (object obj, IntPtr ptr)
static void StructureToPtr (object? obj, IntPtr ptr)
{
if (obj == null)
if (obj is null)
return;
var structType = obj.GetType ();
@ -437,7 +446,7 @@ namespace ObjCRuntime {
static IntPtr WriteStructure (object obj)
{
if (obj == null)
if (obj is null)
return IntPtr.Zero;
if (!obj.GetType ().IsValueType)
@ -462,38 +471,38 @@ namespace ObjCRuntime {
static IntPtr GetAssemblyName (IntPtr gchandle)
{
var asm = (Assembly) GetGCHandleTarget (gchandle);
return Marshal.StringToHGlobalAuto (Path.GetFileName (asm.Location));
var asm = (Assembly?) GetGCHandleTarget (gchandle);
return Marshal.StringToHGlobalAuto (Path.GetFileName (asm?.Location));
}
static IntPtr GetAssemblyLocation (IntPtr gchandle)
{
var asm = (Assembly) GetGCHandleTarget (gchandle);
return Marshal.StringToHGlobalAuto (asm.Location);
var asm = (Assembly?) GetGCHandleTarget (gchandle);
return Marshal.StringToHGlobalAuto (asm?.Location);
}
static void SetFlagsForNSObject (IntPtr gchandle, byte flags)
{
var obj = (NSObject) GetGCHandleTarget (gchandle);
var obj = (NSObject) GetGCHandleTarget (gchandle)!;
obj.FlagsInternal = (NSObject.Flags) flags;
}
static byte GetFlagsForNSObject (IntPtr gchandle)
{
var obj = (NSObject) GetGCHandleTarget (gchandle);
var obj = (NSObject) GetGCHandleTarget (gchandle)!;
return (byte) obj.FlagsInternal;
}
static unsafe MonoObject* GetMethodDeclaringType (MonoObject *mobj)
{
var method = (MethodBase) GetMonoObjectTarget (mobj);
var method = (MethodBase) GetMonoObjectTarget (mobj)!;
return (MonoObject *) GetMonoObject (method.DeclaringType);
}
static IntPtr ObjectGetType (MonoObjectPtr mobj)
{
var obj = GetMonoObjectTarget (mobj);
if (obj == null) {
if (obj is null) {
log_coreclr ($"ObjectGetType (0x{mobj.ToString ("x")}) => null object");
return IntPtr.Zero;
}
@ -502,7 +511,9 @@ namespace ObjCRuntime {
unsafe static sbyte IsDelegate (MonoObject* typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type?) GetMonoObjectTarget (typeobj);
if (type is null)
return 0;
var rv = typeof (MulticastDelegate).IsAssignableFrom (type);
log_coreclr ($"IsDelegate ({type.FullName}) => {rv}");
return (sbyte) (rv ? 1 : 0);
@ -511,10 +522,10 @@ namespace ObjCRuntime {
static sbyte IsInstance (MonoObjectPtr mobj, MonoObjectPtr mtype)
{
var obj = GetMonoObjectTarget (mobj);
if (obj == null)
if (obj is null)
return 0;
var type = (Type) GetMonoObjectTarget (mtype);
var type = (Type) GetMonoObjectTarget (mtype)!;
var rv = type.IsAssignableFrom (obj.GetType ());
log_coreclr ($"IsInstance ({obj.GetType ()}, {type})");
@ -524,8 +535,8 @@ namespace ObjCRuntime {
static unsafe IntPtr GetMethodSignature (MonoObject* methodobj)
{
var method = (MethodBase) GetMonoObjectTarget (methodobj);
var parameters = method.GetParameters ();
var method = (MethodBase) GetMonoObjectTarget (methodobj)!;
var parameters = method.GetParameters ()!;
var parameterCount = parameters.Length;
var rv = Marshal.AllocHGlobal (sizeof (MonoMethodSignature) + sizeof (MonoObjectPtr) * parameterCount);
@ -544,7 +555,7 @@ namespace ObjCRuntime {
return rv;
}
static Type GetMethodReturnType (MethodBase method)
static Type? GetMethodReturnType (MethodBase method)
{
if (method is MethodInfo minfo)
return minfo.ReturnType;
@ -558,30 +569,30 @@ namespace ObjCRuntime {
unsafe static IntPtr ClassGetNamespace (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var rv = type.Namespace;
var type = (Type?) GetMonoObjectTarget (typeobj);
var rv = type?.Namespace;
return Marshal.StringToHGlobalAuto (rv);
}
unsafe static IntPtr ClassGetName (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var rv = type.Name;
var type = (Type?) GetMonoObjectTarget (typeobj);
var rv = type?.Name;
return Marshal.StringToHGlobalAuto (rv);
}
// This should work like mono_class_from_mono_type.
static unsafe MonoObject* TypeToClass (MonoObject* typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
if (type.IsByRef)
var type = (Type?) GetMonoObjectTarget (typeobj);
if (type?.IsByRef == true)
type = type.GetElementType ();
return (MonoObject *) GetMonoObject (type);
}
static unsafe int SizeOf (MonoObject* typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
return SizeOf (type);
}
@ -594,19 +605,19 @@ namespace ObjCRuntime {
static unsafe MonoObject* InvokeMethod (MonoObject* methodobj, MonoObject* instanceobj, IntPtr native_parameters)
{
var method = (MethodBase) GetMonoObjectTarget (methodobj);
var instance = GetMonoObjectTarget (instanceobj);
var method = (MethodBase) GetMonoObjectTarget (methodobj)!;
var instance = GetMonoObjectTarget (instanceobj)!;
var rv = InvokeMethod (method, instance, native_parameters);
return (MonoObject *) GetMonoObject (rv);
}
// Return value: NULL or a MonoObject* that must be released with xamarin_mono_object_safe_release.
// Any MonoObject* ref parameters must also be retained and must be released with xamarin_mono_object_release.
static object InvokeMethod (MethodBase method, object instance, IntPtr native_parameters)
static object? InvokeMethod (MethodBase method, object instance, IntPtr native_parameters)
{
var methodParameters = method.GetParameters ();
var parameters = new object [methodParameters.Length];
var inputParameters = new object [methodParameters.Length];
var parameters = new object? [methodParameters.Length];
var inputParameters = new object? [methodParameters.Length];
var nativeParameters = new IntPtr [methodParameters.Length];
// Copy native array of void* to managed array of IntPtr to make the subsequent code simpler.
@ -618,24 +629,24 @@ namespace ObjCRuntime {
}
// Log our input
log_coreclr ($"InvokeMethod ({method.DeclaringType.FullName}::{method}, {(instance is null ? "<null>" : instance.GetType ().FullName)}, 0x{native_parameters.ToString ("x")})");
log_coreclr ($"InvokeMethod ({method.DeclaringType!.FullName}::{method}, {(instance is null ? "<null>" : instance.GetType ().FullName)}, 0x{native_parameters.ToString ("x")})");
for (var i = 0; i < methodParameters.Length; i++) {
var nativeParam = nativeParameters [i];
var p = methodParameters [i];
var p = methodParameters [i]!;
var paramType = p.ParameterType;
if (paramType.IsByRef)
paramType = paramType.GetElementType ();
log_coreclr ($" Argument #{i + 1}: Type = {p.ParameterType.FullName} IsByRef: {p.ParameterType.IsByRef} IsOut: {p.IsOut} IsClass: {paramType.IsClass} IsInterface: {paramType.IsInterface} NativeParameter: 0x{nativeParam.ToString ("x")}");
paramType = paramType.GetElementType ()!;
log_coreclr ($" Argument #{i + 1}: Type = {p.ParameterType!.FullName} IsByRef: {p.ParameterType!.IsByRef} IsOut: {p.IsOut} IsClass: {paramType.IsClass} IsInterface: {paramType.IsInterface} NativeParameter: 0x{nativeParam.ToString ("x")}");
}
// Process the arguments, and convert to what MethodBase.Invoke expects
for (var i = 0; i < methodParameters.Length; i++) {
var nativeParam = nativeParameters [i];
var p = methodParameters [i];
var paramType = p.ParameterType;
var paramType = p.ParameterType!;
var isByRef = paramType.IsByRef;
if (isByRef)
paramType = paramType.GetElementType ();
paramType = paramType.GetElementType ()!;
log_coreclr ($" Marshalling #{i + 1}: IntPtr => 0x{nativeParam.ToString ("x")} => {p.ParameterType.FullName}");
if (paramType == typeof (IntPtr)) {
@ -668,17 +679,17 @@ namespace ObjCRuntime {
if (nativeParam != IntPtr.Zero) {
// We need to unwrap nullable types and enum types to their underlying struct type.
var structType = paramType;
Type enumType = null;
Type? enumType = null;
if (IsNullable (structType))
structType = Nullable.GetUnderlyingType (structType);
structType = Nullable.GetUnderlyingType (structType)!;
if (structType.IsEnum) {
enumType = structType;
structType = Enum.GetUnderlyingType (structType);
structType = Enum.GetUnderlyingType (structType)!;
}
// convert the pointer to the corresponding structure
var vt = PtrToStructure (nativeParam, structType);
var vt = PtrToStructure (nativeParam, structType)!;
// convert the structure to the enum type if that's what we need
if (enumType != null)
if (enumType is not null)
vt = Enum.ToObject (enumType, vt);
parameters [i] = vt;
}
@ -694,7 +705,7 @@ namespace ObjCRuntime {
// Call the actual method
log_coreclr ($" Invoking...");
object rv = null;
object? rv = null;
try {
rv = method.Invoke (instance, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance, null, parameters, null);
@ -715,7 +726,7 @@ namespace ObjCRuntime {
byrefParameterCount++;
var parameterType = p.ParameterType.GetElementType ();
var parameterType = p.ParameterType.GetElementType ()!;
var isMonoObject = parameterType.IsClass || parameterType.IsInterface || (parameterType.IsValueType && IsNullable (parameterType));
var nativeParam = nativeParameters [i];
@ -729,7 +740,7 @@ namespace ObjCRuntime {
if (parameters [i] == inputParameters [i]) {
log_coreclr ($" The argument didn't change, no marshalling required");
if (parameters [i] != null && parameterType != typeof (IntPtr) && isMonoObject) {
if (parameters [i] is not null && parameterType != typeof (IntPtr) && isMonoObject) {
// byref parameters must be retained
xamarin_mono_object_retain (Marshal.ReadIntPtr (nativeParam));
}
@ -737,7 +748,7 @@ namespace ObjCRuntime {
}
if (parameterType == typeof (IntPtr)) {
Marshal.WriteIntPtr (nativeParam, (IntPtr) parameters [i]);
Marshal.WriteIntPtr (nativeParam, (IntPtr) parameters [i]!);
log_coreclr ($" IntPtr");
} else if (isMonoObject) {
var ptr = GetMonoObject (parameters [i]);
@ -759,7 +770,7 @@ namespace ObjCRuntime {
static unsafe IntPtr StringToUtf8 (MonoObject* obj)
{
var str = (string) GetMonoObjectTarget (obj);
var str = (string?) GetMonoObjectTarget (obj);
return Marshal.StringToHGlobalAuto (str);
}
@ -770,67 +781,67 @@ namespace ObjCRuntime {
static unsafe MonoObject* CreateArray (MonoObject* typeobj, ulong elements)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
var obj = Array.CreateInstance (type, (int) elements);
return (MonoObject*) GetMonoObject (obj);
}
static unsafe ulong GetArrayLength (MonoObject* obj)
{
var array = (Array) GetMonoObjectTarget (obj);
var array = (Array) GetMonoObjectTarget (obj)!;
return (ulong) array.Length;
}
static unsafe void SetArrayObjectValue (MonoObject *arrayobj, ulong index, MonoObject *mobj)
{
var array = (Array) GetMonoObjectTarget (arrayobj);
var array = (Array) GetMonoObjectTarget (arrayobj)!;
var obj = GetMonoObjectTarget (mobj);
array.SetValue (obj, (long) index);
}
static unsafe void SetArrayStructValue (MonoObject *arrayobj, ulong index, MonoObject *typeobj, IntPtr valueptr)
{
var array = (Array) GetMonoObjectTarget (arrayobj);
var elementType = (Type) GetMonoObjectTarget (typeobj);
var array = (Array) GetMonoObjectTarget (arrayobj)!;
var elementType = (Type) GetMonoObjectTarget (typeobj)!;
var obj = Box (elementType, valueptr);
array.SetValue (obj, (long) index);
}
static unsafe MonoObject* GetArrayObjectValue (MonoObject* arrayobj, ulong index)
{
var array = (Array) GetMonoObjectTarget (arrayobj);
var array = (Array) GetMonoObjectTarget (arrayobj)!;
var obj = array.GetValue ((long) index);
return (MonoObject *) GetMonoObject (obj);
}
static unsafe MonoObject* Box (MonoObject* typeobj, IntPtr value)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
var rv = Box (type, value);
return (MonoObject *) GetMonoObject (rv);
}
static object Box (Type type, IntPtr value)
static object? Box (Type type, IntPtr value)
{
var structType = type;
Type enumType = null;
Type? enumType = null;
// We can have a nullable enum value
if (IsNullable (structType)) {
if (value == IntPtr.Zero)
return null;
structType = Nullable.GetUnderlyingType (structType);
structType = Nullable.GetUnderlyingType (structType)!;
}
if (structType.IsEnum) {
// Change to underlying enum type
enumType = structType;
structType = Enum.GetUnderlyingType (structType);
structType = Enum.GetUnderlyingType (structType)!;
}
var boxed = PtrToStructure (value, structType);
if (enumType != null) {
var boxed = PtrToStructure (value, structType)!;
if (enumType is not null) {
// Convert to enum value
boxed = Enum.ToObject (enumType, boxed);
}
@ -840,13 +851,13 @@ namespace ObjCRuntime {
static unsafe sbyte IsNullable (MonoObject* type)
{
var rv = IsNullable ((Type) GetMonoObjectTarget (type));
var rv = IsNullable ((Type) GetMonoObjectTarget (type)!);
return (sbyte) (rv ? 1 : 0);
}
static bool IsNullable (Type type)
{
if (Nullable.GetUnderlyingType (type) != null)
if (Nullable.GetUnderlyingType (type) is not null)
return true;
if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Nullable<>))
@ -857,28 +868,28 @@ namespace ObjCRuntime {
unsafe static sbyte IsByRef (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
var rv = type.IsByRef;
return (sbyte) (rv ? 1 : 0);
}
unsafe static sbyte IsValueType (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
var rv = type.IsValueType;
return (sbyte) (rv ? 1 : 0);
}
unsafe static sbyte IsEnum (MonoObject *typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
var rv = type.IsEnum;
return (sbyte) (rv ? 1 : 0);
}
static unsafe MonoObject* GetEnumBaseType (MonoObject* typeobj)
{
var type = (Type) GetMonoObjectTarget (typeobj);
var type = (Type) GetMonoObjectTarget (typeobj)!;
return (MonoObject*) GetMonoObject (GetEnumBaseType (type));
}
@ -887,7 +898,7 @@ namespace ObjCRuntime {
return type.GetEnumUnderlyingType ();
}
static object PtrToStructure (IntPtr ptr, Type type)
static object? PtrToStructure (IntPtr ptr, Type type)
{
if (ptr == IntPtr.Zero)
return null;
@ -911,13 +922,23 @@ namespace ObjCRuntime {
class ReferenceQueue {
public mono_reference_queue_callback Callback;
public ConditionalWeakTable<object, object> Table = new ConditionalWeakTable<object, object> ();
public ConditionalWeakTable<object, object?> Table = new ConditionalWeakTable<object, object?> ();
public ReferenceQueue (mono_reference_queue_callback callback)
{
Callback = callback;
}
}
class ReferenceQueueEntry {
public ReferenceQueue Queue;
public IntPtr UserData;
public ReferenceQueueEntry (ReferenceQueue queue)
{
Queue = queue;
}
~ReferenceQueueEntry ()
{
Queue.Callback (UserData);
@ -926,17 +947,15 @@ namespace ObjCRuntime {
unsafe static MonoObject* CreateGCReferenceQueue (IntPtr callback)
{
var queue = new ReferenceQueue ();
queue.Callback = Marshal.GetDelegateForFunctionPointer<mono_reference_queue_callback> (callback);
var queue = new ReferenceQueue (Marshal.GetDelegateForFunctionPointer<mono_reference_queue_callback> (callback));
return (MonoObject *) GetMonoObject (queue);
}
unsafe static void GCReferenceQueueAdd (MonoObject* mqueue, MonoObject* mobj, IntPtr user_data)
{
var queue = (ReferenceQueue) GetMonoObjectTarget (mqueue);
var obj = GetMonoObjectTarget (mobj);
var entry = new ReferenceQueueEntry () {
Queue = queue,
var queue = (ReferenceQueue) GetMonoObjectTarget (mqueue)!;
var obj = GetMonoObjectTarget (mobj)!;
var entry = new ReferenceQueueEntry (queue) {
UserData = user_data,
};
queue.Table.Add (obj, entry);
@ -951,7 +970,7 @@ namespace ObjCRuntime {
* Keep a strong reference to the values of the hash table.
*/
class MonoHashTable : IEqualityComparer<IntPtr> {
Dictionary<IntPtr, object> Table;
Dictionary<IntPtr, object?> Table;
HashFunc Hash;
EqualityFunc Compare;
@ -960,17 +979,17 @@ namespace ObjCRuntime {
public MonoHashTable (IntPtr hash_func, IntPtr compare_func)
{
Table = new Dictionary<IntPtr, object> ();
Table = new Dictionary<IntPtr, object?> ();
Hash = Marshal.GetDelegateForFunctionPointer<HashFunc> (hash_func);
Compare = Marshal.GetDelegateForFunctionPointer<EqualityFunc> (compare_func);
}
public void Insert (IntPtr key, object obj)
public void Insert (IntPtr key, object? obj)
{
Table [key] = obj;
}
public object Lookup (IntPtr key)
public object? Lookup (IntPtr key)
{
if (Table.TryGetValue (key, out var value))
return value;
@ -1000,25 +1019,26 @@ namespace ObjCRuntime {
static unsafe void MonoHashTableInsert (MonoObject* tableobj, IntPtr key, MonoObject* valueobj)
{
var table = (MonoHashTable) GetMonoObjectTarget (tableobj);
var table = (MonoHashTable) GetMonoObjectTarget (tableobj)!;
var value = GetMonoObjectTarget (valueobj);
table.Insert (key, value);
}
static unsafe MonoObject* MonoHashTableLookup (MonoObject* tableobj, IntPtr key)
{
var dict = (MonoHashTable) GetMonoObjectTarget (tableobj);
var dict = (MonoHashTable) GetMonoObjectTarget (tableobj)!;
return (MonoObject*) GetMonoObject (dict.Lookup (key));
}
static unsafe IntPtr GetMethodFullName (MonoObject* mobj)
{
return Marshal.StringToHGlobalAuto (GetMethodFullName ((MethodBase) GetMonoObjectTarget (mobj)));
return Marshal.StringToHGlobalAuto (GetMethodFullName ((MethodBase) GetMonoObjectTarget (mobj)!));
}
static string GetMethodFullName (MethodBase method)
[return: NotNullIfNotNull (nameof (method))]
static string? GetMethodFullName (MethodBase? method)
{
if (method == null)
if (method is null)
return null;
// The return value is used in error messages, so there's not a
@ -1028,7 +1048,7 @@ namespace ObjCRuntime {
var sb = new StringBuilder ();
sb.Append (returnType.FullName);
sb.Append (' ');
sb.Append (method.DeclaringType.FullName);
sb.Append (method.DeclaringType!.FullName);
sb.Append ('.');
sb.Append (method.Name);
sb.Append (' ');