return res;
}
-/*
- * mono_marshal_get_castclass:
- * @klass: the type of the field
- *
- * This method generates a function which can be used to cast an object to
- * an instance of the given type, icluding the case where the object is a proxy.
- * The generated function has the following signature:
- * MonoObject* __castclass_wrapper_ (MonoObject *obj)
- */
-MonoMethod *
-mono_marshal_get_castclass (MonoClass *klass)
-{
- static MonoMethodSignature *castclass_sig = NULL;
- GHashTable *cache;
- MonoMethod *res;
-#ifndef DISABLE_REMOTING
- int pos_was_ok, pos_was_ok2;
-#endif
- char *name;
- MonoMethodBuilder *mb;
- WrapperInfo *info;
-
- cache = get_cache (&klass->image->castclass_cache, mono_aligned_addr_hash, NULL);
- if ((res = mono_marshal_find_in_cache (cache, klass)))
- return res;
-
- if (!castclass_sig) {
- castclass_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 1);
- castclass_sig->params [0] = &mono_defaults.object_class->byval_arg;
- castclass_sig->ret = &mono_defaults.object_class->byval_arg;
- castclass_sig->pinvoke = 0;
- }
-
- name = g_strdup_printf ("__castclass_wrapper_%s", klass->name);
- mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_CASTCLASS);
- g_free (name);
-
- mb->method->save_lmf = 1;
-
-#ifndef DISABLE_JIT
- /* check if the object is a proxy that needs special cast */
- mono_mb_emit_ldarg (mb, 0);
- mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- mono_mb_emit_op (mb, CEE_MONO_CCASTCLASS, klass);
-
- /* The result of MONO_CCASTCLASS can be:
- 0) the cast is valid
- 1) cast of unknown proxy type
- or an exception if the cast is is invalid
- */
-#ifndef DISABLE_REMOTING
- pos_was_ok = mono_mb_emit_branch (mb, CEE_BRFALSE);
-
- /* get the real proxy from the transparent proxy*/
-
- mono_mb_emit_ldarg (mb, 0);
- mono_mb_emit_managed_call (mb, mono_marshal_get_proxy_cancast (klass), NULL);
- pos_was_ok2 = mono_mb_emit_branch (mb, CEE_BRTRUE);
-
- /* fail */
- mono_mb_emit_exception (mb, "InvalidCastException", NULL);
-
- /* success */
- mono_mb_patch_branch (mb, pos_was_ok);
- mono_mb_patch_branch (mb, pos_was_ok2);
-#else
- /* MONO_CCASTCLASS leaves an int in the stack with the result, pop it. */
- mono_mb_emit_byte (mb, CEE_POP);
-#endif /* DISABLE_REMOTING */
-
- mono_mb_emit_ldarg (mb, 0);
-
- /* the end */
- mono_mb_emit_byte (mb, CEE_RET);
-#endif /* DISABLE_JIT */
-
- info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
-
- res = mono_mb_create_and_cache_full (cache, klass, mb, castclass_sig, castclass_sig->param_count + 16,
- info, NULL);
- mono_mb_free (mb);
-
- return res;
-}
-
/**
* mono_marshal_get_struct_to_ptr:
* @klass: