#include <mono/metadata/exception-internals.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/reflection-internals.h>
+#include <mono/utils/unlocked.h>
#ifdef ENABLE_LLVM
#include "mini-llvm-cpp.h"
}
#endif
-#if defined(__native_client_codegen__) || defined(__native_client__)
-/* When we cross-compile to Native Client we can't directly embed calls */
-/* to the math library on the host. This will use the fmod on the target*/
-double
-mono_fmod(double a, double b)
-{
- return fmod(a, b);
-}
-#endif
-
gpointer
mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointer *this_arg)
{
gpointer addr;
MonoGenericContext *context = mono_method_get_context (method);
- mono_jit_stats.generic_virtual_invocations++;
+ UnlockedIncrement (&mono_jit_stats.generic_virtual_invocations);
if (obj == NULL) {
mono_set_pending_exception (mono_get_exception_null_reference ());
{
MonoMethod *m;
int vt_slot, iface_offset;
+ gboolean is_iface = FALSE;
error_init (error);
if (mono_class_is_interface (klass)) {
MonoObject *this_obj;
+ is_iface = TRUE;
+
/* Have to use the receiver's type instead of klass, the receiver is a ref type */
this_obj = *(MonoObject**)mp;
g_assert (this_obj);
m = mono_class_inflate_generic_method (m, mono_method_get_context (cmethod));
}
- if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class))
+ if (klass->valuetype && (m->klass == mono_defaults.object_class || m->klass == mono_defaults.enum_class->parent || m->klass == mono_defaults.enum_class)) {
/*
* Calling a non-vtype method with a vtype receiver, has to box.
*/
*this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error);
- else if (klass->valuetype)
- /*
- * Calling a vtype method with a vtype receiver
- */
- *this_arg = mp;
- else
+ } else if (klass->valuetype) {
+ if (is_iface) {
+ /*
+ * The original type is an interface, so the receiver is a ref,
+ the called method is a vtype method, need to unbox.
+ */
+ MonoObject *this_obj = *(MonoObject**)mp;
+
+ *this_arg = mono_object_unbox (this_obj);
+ } else {
+ /*
+ * Calling a vtype method with a vtype receiver
+ */
+ *this_arg = mp;
+ }
+ } else {
/*
* Calling a non-vtype method
*/
*this_arg = *(gpointer*)mp;
+ }
+
return m;
}
void
mono_throw_method_access (MonoMethod *caller, MonoMethod *callee)
{
- char *caller_name = mono_method_full_name (caller, 1);
- char *callee_name = mono_method_full_name (callee, 1);
+ char *caller_name = mono_method_get_reflection_name (caller);
+ char *callee_name = mono_method_get_reflection_name (callee);
MonoError error;
error_init (&error);