Skip to content

Commit

Permalink
[coop] Use handles for mono_runtime_try_invoke_array (dotnet#40614)
Browse files Browse the repository at this point in the history
  • Loading branch information
BrzVlad authored Aug 12, 2020
1 parent 7d25902 commit 13d97e1
Showing 1 changed file with 48 additions and 31 deletions.
79 changes: 48 additions & 31 deletions src/mono/mono/metadata/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -5404,10 +5404,11 @@ mono_runtime_try_exec_main (MonoMethod *method, MonoArray *args, MonoObject **ex
* On failure sets @error and returns NULL.
*/
static gpointer
invoke_array_extract_argument (MonoArray *params, int i, MonoType *t, gboolean* has_byref_nullables, MonoError *error)
invoke_array_extract_argument (MonoArray *params, int i, MonoType *t, MonoObject **pa_obj, gboolean* has_byref_nullables, MonoError *error)
{
MonoType *t_orig = t;
gpointer result = NULL;
*pa_obj = NULL;
error_init (error);
again:
switch (t->type) {
Expand All @@ -5428,7 +5429,8 @@ invoke_array_extract_argument (MonoArray *params, int i, MonoType *t, gboolean*
case MONO_TYPE_VALUETYPE:
if (t->type == MONO_TYPE_VALUETYPE && mono_class_is_nullable (mono_class_from_mono_type_internal (t_orig))) {
/* The runtime invoke wrapper needs the original boxed vtype, it does handle byref values as well. */
result = mono_array_get_internal (params, MonoObject*, i);
*pa_obj = mono_array_get_internal (params, MonoObject*, i);
result = *pa_obj;
if (t->byref)
*has_byref_nullables = TRUE;
} else {
Expand All @@ -5454,8 +5456,8 @@ invoke_array_extract_argument (MonoArray *params, int i, MonoType *t, gboolean*
return_val_if_nok (error, NULL);
mono_array_setref_internal (params, i, copy);
}
result = mono_object_unbox_internal (mono_array_get_internal (params, MonoObject*, i));
*pa_obj = mono_array_get_internal (params, MonoObject*, i);
result = mono_object_unbox_internal (*pa_obj);
if (!t->byref && was_null)
mono_array_setref_internal (params, i, NULL);
}
Expand All @@ -5465,11 +5467,13 @@ invoke_array_extract_argument (MonoArray *params, int i, MonoType *t, gboolean*
case MONO_TYPE_CLASS:
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY:
if (t->byref)
if (t->byref) {
result = mono_array_addr_internal (params, MonoObject*, i);
// FIXME: I need to check this code path
else
result = mono_array_get_internal (params, MonoObject*, i);
} else {
*pa_obj = mono_array_get_internal (params, MonoObject*, i);
result = *pa_obj;
}
break;
case MONO_TYPE_GENERICINST:
if (t->byref)
Expand Down Expand Up @@ -5638,21 +5642,25 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
MonoObject **exc, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
HANDLE_FUNCTION_ENTER ();

error_init (error);

MonoMethodSignature *sig = mono_method_signature_internal (method);
gpointer *pa = NULL;
MonoObject *res;
MonoObject *res = NULL;
int i;
gboolean has_byref_nullables = FALSE;

if (NULL != params) {
pa = g_newa (gpointer, mono_array_length_internal (params));
for (i = 0; i < mono_array_length_internal (params); i++) {
MonoType *t = sig->params [i];
pa [i] = invoke_array_extract_argument (params, i, t, &has_byref_nullables, error);
return_val_if_nok (error, NULL);
MonoObject *pa_obj;
pa [i] = invoke_array_extract_argument (params, i, t, &pa_obj, &has_byref_nullables, error);
if (pa_obj)
MONO_HANDLE_PIN (pa_obj);
goto_if_nok (error, exit_null);
}
}

Expand All @@ -5663,16 +5671,18 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
/* Need to create a boxed vtype instead */
g_assert (!obj);

if (!params)
return NULL;
else {
return mono_value_box_checked (mono_domain_get (), m_class_get_cast_class (method->klass), pa [0], error);
if (!params) {
goto_if_nok (error, exit_null);
} else {
res = mono_value_box_checked (mono_domain_get (), m_class_get_cast_class (method->klass), pa [0], error);
goto exit;
}
}

if (!obj) {
obj = mono_object_new_checked (mono_domain_get (), method->klass, error);
return_val_if_nok (error, NULL);
MonoObjectHandle obj_h = mono_object_new_handle (mono_domain_get (), method->klass, error);
goto_if_nok (error, exit_null);
obj = MONO_HANDLE_RAW (obj_h);
g_assert (obj); /*maybe we should raise a TLE instead?*/
#ifndef DISABLE_REMOTING
if (mono_object_is_transparent_proxy (obj)) {
Expand All @@ -5685,8 +5695,9 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
else
o = obj;
} else if (m_class_is_valuetype (method->klass)) {
obj = mono_value_box_checked (mono_domain_get (), method->klass, obj, error);
return_val_if_nok (error, NULL);
MonoObjectHandle obj_h = mono_value_box_handle (mono_domain_get (), method->klass, obj, error);
goto_if_nok (error, exit_null);
obj = MONO_HANDLE_RAW (obj_h);
}

if (exc) {
Expand All @@ -5695,20 +5706,20 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
mono_runtime_invoke_checked (method, o, pa, error);
}

return (MonoObject *)obj;
res = (MonoObject*)obj;
} else {
if (mono_class_is_nullable (method->klass)) {
if (method->flags & METHOD_ATTRIBUTE_STATIC) {
obj = NULL;
} else {
MonoObject *nullable;
/* Convert the unboxed vtype into a Nullable structure */
nullable = mono_object_new_checked (mono_domain_get (), method->klass, error);
return_val_if_nok (error, NULL);
MonoObjectHandle nullable_h = mono_object_new_handle (mono_domain_get (), method->klass, error);
goto_if_nok (error, exit_null);
MonoObject* nullable = MONO_HANDLE_RAW (nullable_h);

MonoObject *boxed = mono_value_box_checked (mono_domain_get (), m_class_get_cast_class (method->klass), obj, error);
return_val_if_nok (error, NULL);
mono_nullable_init ((guint8 *)mono_object_unbox_internal (nullable), boxed, method->klass);
MonoObjectHandle boxed_h = mono_value_box_handle (mono_domain_get (), m_class_get_cast_class (method->klass), obj, error);
goto_if_nok (error, exit_null);
mono_nullable_init ((guint8 *)mono_object_unbox_internal (nullable), MONO_HANDLE_RAW (boxed_h), method->klass);
obj = mono_object_unbox_internal (nullable);
}
}
Expand All @@ -5719,7 +5730,8 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
} else {
res = mono_runtime_invoke_checked (method, obj, pa, error);
}
return_val_if_nok (error, NULL);
MONO_HANDLE_PIN (res);
goto_if_nok (error, exit_null);

if (sig->ret->type == MONO_TYPE_PTR) {
MonoClass *pointer_class;
Expand Down Expand Up @@ -5748,12 +5760,14 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
// byref is already unboxed by the invoke code
MonoType *tmpret = mono_metadata_type_dup (NULL, sig->ret);
tmpret->byref = FALSE;
box_args [1] = mono_type_get_object_checked (mono_domain_get (), tmpret, error);
MonoReflectionTypeHandle type_h = mono_type_get_object_handle (mono_domain_get (), tmpret, error);
box_args [1] = MONO_HANDLE_RAW (type_h);
mono_metadata_free_type (tmpret);
} else {
box_args [1] = mono_type_get_object_checked (mono_domain_get (), sig->ret, error);
MonoReflectionTypeHandle type_h = mono_type_get_object_handle (mono_domain_get (), sig->ret, error);
box_args [1] = MONO_HANDLE_RAW (type_h);
}
return_val_if_nok (error, NULL);
goto_if_nok (error, exit_null);

res = mono_runtime_try_invoke (box_method, NULL, box_args, &box_exc, error);
g_assert (box_exc == NULL);
Expand All @@ -5773,9 +5787,12 @@ mono_runtime_try_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
mono_array_setref_internal (params, i, pa [i]);
}
}

return res;
}
goto exit;
exit_null:
res = NULL;
exit:
HANDLE_FUNCTION_RETURN_VAL (res);
}

// FIXME these will move to header soon
Expand Down

0 comments on commit 13d97e1

Please sign in to comment.