X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fjit-icalls.c;h=45c7689a58ab09bf9e100b53049471ffabae6ab5;hb=46cccd7feb93e124594e2b225dbca2b3ab0164ea;hp=78db84f7fd30d03c011f17c5c2a892dd2a1c044b;hpb=35a7005b75e1b6e03560b4970eacc62cc9224fc1;p=mono.git diff --git a/mono/mini/jit-icalls.c b/mono/mini/jit-icalls.c index 78db84f7fd3..45c7689a58a 100644 --- a/mono/mini/jit-icalls.c +++ b/mono/mini/jit-icalls.c @@ -82,7 +82,7 @@ mono_helper_stelem_ref_check (MonoArray *array, MonoObject *val) mono_raise_exception (mono_get_exception_array_type_mismatch ()); } -#ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS +#if !defined(MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS) || defined(MONO_ARCH_EMULATE_LONG_MUL_OVF_OPTS) gint64 mono_llmult (gint64 a, gint64 b) @@ -429,7 +429,7 @@ mono_imul_ovf_un (guint32 a, guint32 b) } #endif -#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT) +#if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT_FALLBACK) double mono_fdiv (double a, double b) { @@ -439,7 +439,7 @@ mono_fdiv (double a, double b) } #endif -#ifdef MONO_ARCH_SOFT_FLOAT +#ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK double mono_fsub (double a, double b) @@ -871,6 +871,13 @@ guint32 mono_fconv_u4 (double v) { /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/ + + /* MS.NET behaves like this for some reason */ +#ifdef HAVE_ISINF + if (isinf (v) || isnan (v)) + return 0; +#endif + return (guint32)v; } @@ -915,7 +922,7 @@ mono_fconv_ovf_u8 (double v) * * To work around this issue we test for value boundaries instead. */ -#if defined(__arm__) && MONO_ARCH_SOFT_FLOAT +#if defined(__arm__) && defined(MONO_ARCH_SOFT_FLOAT_FALLBACK) if (isnan (v) || !(v >= -0.5 && v <= ULLONG_MAX+0.5)) { mono_raise_exception (mono_get_exception_overflow ()); } @@ -989,8 +996,7 @@ mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointe addr = mono_compile_method (vmethod); - if (mono_method_needs_static_rgctx_invoke (vmethod, FALSE)) - addr = mono_create_static_rgctx_trampoline (vmethod, addr); + addr = mini_add_method_trampoline (NULL, vmethod, addr, mono_method_needs_static_rgctx_invoke (vmethod, FALSE), FALSE); /* Since this is a virtual call, have to unbox vtypes */ if (obj->vtable->klass->valuetype) @@ -1052,7 +1058,7 @@ mono_create_corlib_exception_2 (guint32 token, MonoString *arg1, MonoString *arg } MonoObject* -mono_object_castclass (MonoObject *obj, MonoClass *klass) +mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass) { MonoJitTlsData *jit_tls = NULL; @@ -1064,6 +1070,8 @@ mono_object_castclass (MonoObject *obj, MonoClass *klass) if (!obj) return NULL; + if (klass->enumtype && obj->vtable->klass == klass->element_class) + return obj; if (mono_object_isinst (obj, klass)) return obj; @@ -1160,11 +1168,26 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k MonoMethod *m; int vt_slot; - /* Lookup the virtual method */ - mono_class_setup_vtable (klass); - g_assert (klass->vtable); - vt_slot = mono_method_get_vtable_slot (cmethod); - m = klass->vtable [vt_slot]; + if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) + mono_raise_exception (mono_get_exception_execution_engine ("Not yet supported.")); + + if (mono_method_signature (cmethod)->pinvoke) { + /* Object.GetType () */ + m = mono_marshal_get_native_wrapper (cmethod, TRUE, FALSE); + } else { + /* Lookup the virtual method */ + mono_class_setup_vtable (klass); + g_assert (klass->vtable); + vt_slot = mono_method_get_vtable_slot (cmethod); + if (cmethod->klass->flags & TYPE_ATTRIBUTE_INTERFACE) { + int iface_offset; + + iface_offset = mono_class_interface_offset (klass, cmethod->klass); + g_assert (iface_offset != -1); + vt_slot += iface_offset; + } + m = klass->vtable [vt_slot]; + } 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. @@ -1183,46 +1206,31 @@ constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *k return m; } +/* + * mono_gsharedvt_constrained_call: + * + * Make a call to CMETHOD using the receiver MP, which is assumed to be of type KLASS. ARGS contains + * the arguments to the method in the format used by mono_runtime_invoke (). + */ MonoObject* -mono_object_tostring_gsharedvt (gpointer mp, MonoMethod *cmethod, MonoClass *klass) +mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args) { MonoMethod *m; gpointer this_arg; + gpointer new_args [16]; m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg); - return mono_runtime_invoke (m, this_arg, NULL, NULL); -} - -int -mono_object_gethashcode_gsharedvt (gpointer mp, MonoMethod *cmethod, MonoClass *klass) -{ - MonoMethod *m; - gpointer this_arg; - MonoObject *res; - gpointer p; - - m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg); - // FIXME: This boxes the result - res = mono_runtime_invoke (m, this_arg, NULL, NULL); - p = mono_object_unbox (res); - return *(int*)p; -} - -MonoBoolean -mono_object_equals_gsharedvt (gpointer mp, MonoMethod *cmethod, MonoClass *klass, MonoObject *arg) -{ - MonoMethod *m; - gpointer this_arg; - MonoObject *res; - gpointer p; - void **args; - - m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg); - // FIXME: This boxes the result - args = (void**)&arg; - res = mono_runtime_invoke (m, this_arg, args, NULL); - p = mono_object_unbox (res); - return *(MonoBoolean*)p; + if (args && deref_arg) { + new_args [0] = *(gpointer*)args [0]; + args = new_args; + } + if (m->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) { + /* Object.GetType () */ + args = new_args; + args [0] = this_arg; + this_arg = NULL; + } + return mono_runtime_invoke (m, this_arg, args, NULL); } void