Skip to content

Commit

Permalink
[runtime] copy updated byref nullables after invoke (#67652)
Browse files Browse the repository at this point in the history
* [runtime] copy updated byref nullables after invoke

Bring back some code lost in
#60270

When a `null` is passed for a `ref Nullable<S>` argument to a runtime
invoke, the invoke wrapper creates a default `Nullable` that should be
copied back into the original arguments array of the invoke.

There is code in the managed `Invoke` method to do some of the copying from the temporary
array that is created for the Invoke (we pass a `Span<object>` over
that array from managed to native), but in
`mono_runtime_try_invoke_span` we create a C array `pa` that has the
arguments (this takes care of by-value semantics for value types, for
example).  We need to copy the byref nullables back from `pa` to the
span, so that managed code can then copy it back from the span to the
original input array of the Invoke.

Fixes #67269
  • Loading branch information
lambdageek authored Apr 9, 2022
1 parent d09f42d commit 285b825
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 2 deletions.
2 changes: 0 additions & 2 deletions src/libraries/System.Reflection/tests/MethodInfoTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,6 @@ public void ToStringTest_ByMethodInfo(MethodInfo methodInfo, string expected)
Assert.Equal(expected, methodInfo.ToString());
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/67269", TestRuntimes.Mono)]
[Fact]
public void InvokeNullableRefs()
{
Expand Down Expand Up @@ -656,7 +655,6 @@ static MethodInfo GetMethod(string name) => typeof(NullableRefMethods).GetMethod
name, BindingFlags.Public | BindingFlags.Static)!;
}

[ActiveIssue("https://github.com/dotnet/runtime/issues/67269", TestRuntimes.Mono)]
[Fact]
public void InvokeBoxedNullableRefs()
{
Expand Down
14 changes: 14 additions & 0 deletions src/mono/mono/metadata/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -4841,6 +4841,20 @@ mono_runtime_try_invoke_span (MonoMethod *method, void *obj, MonoSpanOfObjects *
g_assert (box_exc == NULL);
mono_error_assert_ok (error);
}

if (has_byref_nullables) {
/*
* The runtime invoke wrapper already converted byref nullables back,
* and stored them in pa, we just need to copy them back to the
* managed array.
*/
for (i = 0; i < params_length; i++) {
MonoType *t = sig->params [i];

if (m_type_is_byref (t) && t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type_internal (t)))
mono_span_setref (params_span, i, pa [i]);
}
}
}
goto exit;
exit_null:
Expand Down

0 comments on commit 285b825

Please sign in to comment.