+
+/*
+ * On some architectures, gdb doesn't like encountering the cpu breakpoint instructions
+ * in generated code. So instead we emit a call to this function and place a gdb
+ * breakpoint here.
+ */
+void
+mono_break (void)
+{
+}
+
+MonoException *
+mono_create_corlib_exception_0 (guint32 token)
+{
+ return mono_exception_from_token (mono_defaults.corlib, token);
+}
+
+MonoException *
+mono_create_corlib_exception_1 (guint32 token, MonoString *arg)
+{
+ return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg, NULL);
+}
+
+MonoException *
+mono_create_corlib_exception_2 (guint32 token, MonoString *arg1, MonoString *arg2)
+{
+ return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg1, arg2);
+}
+
+MonoObject*
+mono_object_castclass (MonoObject *obj, MonoClass *klass)
+{
+ MonoJitTlsData *jit_tls = NULL;
+
+ if (mini_get_debug_options ()->better_cast_details) {
+ jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+ jit_tls->class_cast_from = NULL;
+ }
+
+ if (!obj)
+ return NULL;
+
+ if (mono_object_isinst (obj, klass))
+ return obj;
+
+ if (mini_get_debug_options ()->better_cast_details) {
+ jit_tls->class_cast_from = obj->vtable->klass;
+ jit_tls->class_cast_to = klass;
+ }
+
+ mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
+ "System", "InvalidCastException"));
+
+ return NULL;
+}
+
+MonoObject*
+mono_object_castclass_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cache)
+{
+ MonoJitTlsData *jit_tls = NULL;
+ gpointer cached_vtable, obj_vtable;
+
+ if (mini_get_debug_options ()->better_cast_details) {
+ jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
+ jit_tls->class_cast_from = NULL;
+ }
+
+ if (!obj)
+ return NULL;
+
+ cached_vtable = *cache;
+ obj_vtable = obj->vtable;
+
+ if (cached_vtable == obj_vtable)
+ return obj;
+
+ if (mono_object_isinst (obj, klass)) {
+ *cache = obj_vtable;
+ return obj;
+ }
+
+ if (mini_get_debug_options ()->better_cast_details) {
+ jit_tls->class_cast_from = obj->vtable->klass;
+ jit_tls->class_cast_to = klass;
+ }
+
+ mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
+ "System", "InvalidCastException"));
+
+ return NULL;
+}
+
+MonoObject*
+mono_object_isinst_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cache)
+{
+ size_t cached_vtable, obj_vtable;
+
+ if (!obj)
+ return NULL;
+
+ cached_vtable = (size_t)*cache;
+ obj_vtable = (size_t)obj->vtable;
+
+ if ((cached_vtable & ~0x1) == obj_vtable) {
+ return (cached_vtable & 0x1) ? NULL : obj;
+ }
+
+ if (mono_object_isinst (obj, klass)) {
+ *cache = (gpointer)obj_vtable;
+ return obj;
+ } else {
+ /*negative cache*/
+ *cache = (gpointer)(obj_vtable | 0x1);
+ return NULL;
+ }
+}
+
+gpointer
+mono_get_native_calli_wrapper (MonoImage *image, MonoMethodSignature *sig, gpointer func)
+{
+ MonoMarshalSpec **mspecs;
+ MonoMethodPInvoke piinfo;
+ MonoMethod *m;
+
+ mspecs = g_new0 (MonoMarshalSpec*, sig->param_count + 1);
+ memset (&piinfo, 0, sizeof (piinfo));
+
+ m = mono_marshal_get_native_func_wrapper (image, sig, &piinfo, mspecs, func);
+
+ return mono_compile_method (m);
+}