2 * marshal.c: Routines for marshaling complex types in P/Invoke methods.
5 * Paolo Molaro (lupus@ximian.com)
7 * (C) 2002 Ximian, Inc. http://www.ximian.com
14 #include "metadata/marshal.h"
15 #include "metadata/tabledefs.h"
16 #include "metadata/exception.h"
17 #include "metadata/appdomain.h"
18 #include "mono/metadata/debug-helpers.h"
19 #include "mono/metadata/threadpool.h"
21 //#define DEBUG_RUNTIME_CODE
23 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
27 #include "mono/cil/opcode.def"
32 struct _MonoMethodBuilder {
36 guint32 code_size, pos;
40 #ifdef DEBUG_RUNTIME_CODE
42 indenter (MonoDisHelper *dh, MonoMethod *method, guint32 ip_offset)
44 return g_strdup (" ");
47 static MonoDisHelper marshal_dh = {
58 mono_delegate_to_ftnptr (MonoDelegate *delegate)
60 MonoMethod *method, *wrapper;
66 if (delegate->delegate_trampoline)
67 return delegate->delegate_trampoline;
69 klass = ((MonoObject *)delegate)->vtable->klass;
70 g_assert (klass->delegate);
72 method = delegate->method_info->method;
74 wrapper = mono_marshal_get_managed_wrapper (method, (MonoObject *)delegate);
76 delegate->delegate_trampoline = mono_compile_method (wrapper);
78 return delegate->delegate_trampoline;
82 mono_array_to_savearray (MonoArray *array)
87 g_assert_not_reached ();
92 mono_array_to_lparray (MonoArray *array)
97 /* fixme: maybe we need to make a copy */
102 mono_string_to_ansibstr (MonoString *string_obj)
104 g_error ("implement me");
109 mono_string_to_bstr (MonoString *string_obj)
111 g_error ("implement me");
116 mono_string_to_byvalstr (gpointer dst, MonoString *src, int size)
121 g_assert (dst != NULL);
125 memset (dst, 0, size);
129 s = mono_string_to_utf8 (src);
130 len = MIN (size, strlen (s));
131 memcpy (dst, s, len);
134 *((char *)dst + size - 1) = 0;
138 mono_string_to_byvalwstr (gpointer dst, MonoString *src, int size)
142 g_assert (dst != NULL);
146 memset (dst, 0, size);
150 len = MIN (size, (mono_string_length (src) * 2));
151 memcpy (dst, mono_string_chars (src), len);
153 *((char *)dst + size - 1) = 0;
154 *((char *)dst + size - 2) = 0;
159 mono_find_method_by_name (MonoClass *klass, const char *name, int param_count)
161 MonoMethod *res = NULL;
164 for (i = 0; i < klass->method.count; ++i) {
165 if ((klass->methods [i]->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
166 klass->methods [i]->name[0] == name [0] &&
167 !strcmp (name, klass->methods [i]->name) &&
168 klass->methods [i]->signature->param_count == param_count) {
169 res = klass->methods [i];
177 mono_mb_free (MonoMethodBuilder *mb)
179 g_list_free (mb->locals_list);
184 mono_mb_new (MonoClass *klass, const char *name)
186 MonoMethodBuilder *mb;
189 g_assert (klass != NULL);
190 g_assert (name != NULL);
192 mb = g_new0 (MonoMethodBuilder, 1);
194 mb->method = m = (MonoMethod *)g_new0 (MonoMethodWrapper, 1);
197 m->name = g_strdup (name);
199 m->inline_count = -1;
200 m->wrapper_type = MONO_WRAPPER_UNKNOWN;
203 mb->code = g_malloc (mb->code_size);
209 mono_mb_add_local (MonoMethodBuilder *mb, MonoType *type)
211 int res = mb->locals;
213 g_assert (mb != NULL);
214 g_assert (type != NULL);
216 mb->locals_list = g_list_append (mb->locals_list, type);
223 mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack)
225 MonoMethodHeader *header;
229 g_assert (mb != NULL);
231 ((MonoMethodNormal *)mb->method)->header = header = (MonoMethodHeader *)
232 g_malloc0 (sizeof (MonoMethodHeader) + mb->locals * sizeof (MonoType *));
237 header->max_stack = max_stack;
239 for (i = 0, l = mb->locals_list; l; l = l->next, i++) {
240 header->locals [i] = (MonoType *)l->data;
243 mb->method->signature = signature;
244 header->code = mb->code;
245 header->code_size = mb->pos;
246 header->num_locals = mb->locals;
248 #ifdef DEBUG_RUNTIME_CODE
249 printf ("RUNTIME CODE FOR %s\n", mono_method_full_name (mb->method, TRUE));
250 printf ("%s\n", mono_disasm_code (&marshal_dh, mb->method, mb->code, mb->code + mb->pos));
257 mono_mb_add_data (MonoMethodBuilder *mb, gpointer data)
259 MonoMethodWrapper *mw;
261 g_assert (mb != NULL);
263 mw = (MonoMethodWrapper *)mb->method;
265 mw->data = g_list_append (mw->data, data);
267 return g_list_length (mw->data);
271 mono_mb_patch_addr (MonoMethodBuilder *mb, int pos, int value)
273 *((gint32 *)(&mb->code [pos])) = value;
277 mono_mb_emit_byte (MonoMethodBuilder *mb, guint8 op)
279 if (mb->pos >= mb->code_size) {
281 mb->code = g_realloc (mb->code, mb->code_size);
284 mb->code [mb->pos++] = op;
288 mono_mb_emit_i4 (MonoMethodBuilder *mb, gint32 data)
290 if ((mb->pos + 4) >= mb->code_size) {
292 mb->code = g_realloc (mb->code, mb->code_size);
295 *((gint32 *)(&mb->code [mb->pos])) = data;
300 mono_mb_emit_i2 (MonoMethodBuilder *mb, gint16 data)
302 if ((mb->pos + 2) >= mb->code_size) {
304 mb->code = g_realloc (mb->code, mb->code_size);
307 *((gint16 *)(&mb->code [mb->pos])) = data;
312 mono_mb_emit_ldarg (MonoMethodBuilder *mb, guint argnum)
315 mono_mb_emit_byte (mb, CEE_LDARG_0 + argnum);
316 } else if (argnum < 256) {
317 mono_mb_emit_byte (mb, CEE_LDARG_S);
318 mono_mb_emit_byte (mb, argnum);
320 mono_mb_emit_byte (mb, CEE_PREFIX1);
321 mono_mb_emit_byte (mb, CEE_LDARG);
322 mono_mb_emit_i4 (mb, argnum);
327 mono_mb_emit_ldarg_addr (MonoMethodBuilder *mb, guint argnum)
330 mono_mb_emit_byte (mb, CEE_LDARGA_S);
331 mono_mb_emit_byte (mb, argnum);
333 mono_mb_emit_byte (mb, CEE_PREFIX1);
334 mono_mb_emit_byte (mb, CEE_LDARGA);
335 mono_mb_emit_i4 (mb, argnum);
340 mono_mb_emit_ldloc_addr (MonoMethodBuilder *mb, guint locnum)
343 mono_mb_emit_byte (mb, CEE_LDLOCA_S);
344 mono_mb_emit_byte (mb, locnum);
346 mono_mb_emit_byte (mb, CEE_PREFIX1);
347 mono_mb_emit_byte (mb, CEE_LDLOCA);
348 mono_mb_emit_i4 (mb, locnum);
353 mono_mb_emit_ldloc (MonoMethodBuilder *mb, guint num)
356 mono_mb_emit_byte (mb, CEE_LDLOC_0 + num);
357 } else if (num < 256) {
358 mono_mb_emit_byte (mb, CEE_LDLOC_S);
359 mono_mb_emit_byte (mb, num);
361 mono_mb_emit_byte (mb, CEE_PREFIX1);
362 mono_mb_emit_byte (mb, CEE_LDLOC);
363 mono_mb_emit_i4 (mb, num);
368 mono_mb_emit_stloc (MonoMethodBuilder *mb, guint num)
371 mono_mb_emit_byte (mb, CEE_STLOC_0 + num);
372 } else if (num < 256) {
373 mono_mb_emit_byte (mb, CEE_STLOC_S);
374 mono_mb_emit_byte (mb, num);
376 mono_mb_emit_byte (mb, CEE_PREFIX1);
377 mono_mb_emit_byte (mb, CEE_STLOC);
378 mono_mb_emit_i4 (mb, num);
383 mono_mb_emit_icon (MonoMethodBuilder *mb, gint32 value)
385 if (value >= -1 && value < 8) {
386 mono_mb_emit_byte (mb, CEE_LDC_I4_0 + value);
387 } else if (value >= -128 && value <= 127) {
388 mono_mb_emit_byte (mb, CEE_LDC_I4_S);
389 mono_mb_emit_byte (mb, value);
391 mono_mb_emit_byte (mb, CEE_LDC_I4);
392 mono_mb_emit_i4 (mb, value);
397 mono_mb_emit_managed_call (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *opt_sig)
400 opt_sig = method->signature;
401 mono_mb_emit_byte (mb, CEE_PREFIX1);
402 mono_mb_emit_byte (mb, CEE_LDFTN);
403 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, method));
404 mono_mb_emit_byte (mb, CEE_CALLI);
405 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, opt_sig));
409 mono_mb_emit_native_call (MonoMethodBuilder *mb, MonoMethodSignature *sig, gpointer func)
411 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
412 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
413 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, func));
414 mono_mb_emit_byte (mb, CEE_CALLI);
415 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, sig));
419 mono_mb_emit_exception (MonoMethodBuilder *mb)
421 mono_mb_emit_byte (mb, CEE_LDNULL);
422 mono_mb_emit_byte (mb, CEE_THROW);
427 mono_mb_emit_add_to_local (MonoMethodBuilder *mb, guint8 local, gint8 incr)
429 mono_mb_emit_ldloc (mb, local);
430 mono_mb_emit_icon (mb, incr);
431 mono_mb_emit_byte (mb, CEE_ADD);
432 mono_mb_emit_stloc (mb, local);
436 emit_ptr_to_str_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv,
437 int usize, int msize)
440 case MONO_MARSHAL_CONV_BOOL_I4:
441 mono_mb_emit_byte (mb, CEE_LDLOC_0);
442 mono_mb_emit_byte (mb, CEE_LDIND_I);
443 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
444 mono_mb_emit_byte (mb, 5);
445 mono_mb_emit_byte (mb, CEE_LDLOC_1);
446 mono_mb_emit_byte (mb, CEE_LDC_I4_1);
447 mono_mb_emit_byte (mb, CEE_STIND_I1);
448 mono_mb_emit_byte (mb, CEE_BR_S);
449 mono_mb_emit_byte (mb, 3);
450 mono_mb_emit_byte (mb, CEE_LDLOC_1);
451 mono_mb_emit_byte (mb, CEE_LDC_I4_0);
452 mono_mb_emit_byte (mb, CEE_STIND_I1);
454 case MONO_MARSHAL_CONV_ARRAY_BYVALARRAY: {
458 if (type->type == MONO_TYPE_ARRAY)
459 eclass = mono_class_from_mono_type (type->data.array->type);
460 else if (type->type == MONO_TYPE_SZARRAY) {
461 eclass = mono_class_from_mono_type (type->data.type);
463 g_assert_not_reached ();
466 if (eclass->valuetype)
467 esize = mono_class_instance_size (eclass) - sizeof (MonoObject);
469 esize = sizeof (gpointer);
471 /* create a new array */
472 mono_mb_emit_byte (mb, CEE_LDLOC_1);
473 mono_mb_emit_icon (mb, msize / esize);
474 mono_mb_emit_byte (mb, CEE_NEWARR);
475 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, eclass));
476 mono_mb_emit_byte (mb, CEE_STIND_I);
478 /* copy the elements */
479 mono_mb_emit_byte (mb, CEE_LDLOC_1);
480 mono_mb_emit_byte (mb, CEE_LDIND_I);
481 mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoArray, vector));
482 mono_mb_emit_byte (mb, CEE_ADD);
483 mono_mb_emit_byte (mb, CEE_LDLOC_0);
484 mono_mb_emit_icon (mb, usize);
485 mono_mb_emit_byte (mb, CEE_PREFIX1);
486 mono_mb_emit_byte (mb, CEE_CPBLK);
490 case MONO_MARSHAL_CONV_STR_BYVALSTR:
491 mono_mb_emit_byte (mb, CEE_LDLOC_1);
492 mono_mb_emit_byte (mb, CEE_LDLOC_0);
493 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
494 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
495 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
496 mono_mb_emit_byte (mb, CEE_STIND_I);
498 case MONO_MARSHAL_CONV_STR_LPTSTR:
499 case MONO_MARSHAL_CONV_STR_LPSTR:
500 mono_mb_emit_byte (mb, CEE_LDLOC_1);
501 mono_mb_emit_byte (mb, CEE_LDLOC_0);
502 mono_mb_emit_byte (mb, CEE_LDIND_I);
503 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
504 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
505 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
506 mono_mb_emit_byte (mb, CEE_STIND_I);
508 case MONO_MARSHAL_CONV_STR_LPWSTR:
509 case MONO_MARSHAL_CONV_STR_BSTR:
510 case MONO_MARSHAL_CONV_STR_ANSIBSTR:
511 case MONO_MARSHAL_CONV_STR_TBSTR:
512 case MONO_MARSHAL_CONV_ARRAY_SAVEARRAY:
513 case MONO_MARSHAL_CONV_ARRAY_LPARRAY:
514 case MONO_MARSHAL_CONV_STR_BYVALWSTR:
515 case MONO_MARSHAL_CONV_BOOL_VARIANTBOOL:
517 g_warning ("marshalling conversion %d not implemented", conv);
518 g_assert_not_reached ();
523 emit_str_to_ptr_conv (MonoMethodBuilder *mb, MonoMarshalConv conv, int usize, int msize)
526 case MONO_MARSHAL_CONV_BOOL_I4:
527 mono_mb_emit_byte (mb, CEE_LDLOC_1);
528 mono_mb_emit_byte (mb, CEE_LDLOC_0);
529 mono_mb_emit_byte (mb, CEE_LDIND_U1);
530 mono_mb_emit_byte (mb, CEE_STIND_I4);
532 case MONO_MARSHAL_CONV_STR_LPWSTR:
533 case MONO_MARSHAL_CONV_STR_LPSTR:
534 case MONO_MARSHAL_CONV_STR_LPTSTR:
535 case MONO_MARSHAL_CONV_STR_BSTR:
536 case MONO_MARSHAL_CONV_STR_ANSIBSTR:
537 case MONO_MARSHAL_CONV_STR_TBSTR:
538 case MONO_MARSHAL_CONV_ARRAY_SAVEARRAY:
539 case MONO_MARSHAL_CONV_ARRAY_LPARRAY:
540 /* free space if free == true */
541 mono_mb_emit_byte (mb, CEE_LDLOC_2);
542 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
543 mono_mb_emit_byte (mb, 4);
544 mono_mb_emit_byte (mb, CEE_LDLOC_1);
545 mono_mb_emit_byte (mb, CEE_LDIND_I);
546 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
547 mono_mb_emit_byte (mb, CEE_MONO_FREE);
549 mono_mb_emit_byte (mb, CEE_LDLOC_1);
550 mono_mb_emit_byte (mb, CEE_LDLOC_0);
551 mono_mb_emit_byte (mb, CEE_LDIND_I);
552 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
553 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
554 mono_mb_emit_byte (mb, conv);
555 mono_mb_emit_byte (mb, CEE_STIND_I);
557 case MONO_MARSHAL_CONV_STR_BYVALSTR:
558 case MONO_MARSHAL_CONV_STR_BYVALWSTR: {
562 mono_mb_emit_byte (mb, CEE_LDLOC_1); /* dst */
563 mono_mb_emit_byte (mb, CEE_LDLOC_0);
564 mono_mb_emit_byte (mb, CEE_LDIND_I); /* src String */
565 mono_mb_emit_icon (mb, usize);
566 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
567 mono_mb_emit_byte (mb, CEE_MONO_PROC3);
568 mono_mb_emit_byte (mb, conv);
571 case MONO_MARSHAL_CONV_ARRAY_BYVALARRAY: {
575 mono_mb_emit_byte (mb, CEE_LDLOC_0);
576 mono_mb_emit_byte (mb, CEE_LDIND_I);
577 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
578 mono_mb_emit_byte (mb, 15);
580 mono_mb_emit_byte (mb, CEE_LDLOC_1);
581 mono_mb_emit_byte (mb, CEE_LDLOC_0);
582 mono_mb_emit_byte (mb, CEE_LDIND_I);
583 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
584 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
585 mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoArray, vector));
586 mono_mb_emit_byte (mb, CEE_ADD);
587 mono_mb_emit_icon (mb, usize);
588 mono_mb_emit_byte (mb, CEE_PREFIX1);
589 mono_mb_emit_byte (mb, CEE_CPBLK);
592 case MONO_MARSHAL_CONV_BOOL_VARIANTBOOL:
594 g_warning ("marshalling conversion %d not implemented", conv);
595 g_assert_not_reached ();
600 emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
602 MonoMarshalType *info;
605 info = mono_marshal_load_type_info (klass);
607 for (i = 0; i < info->num_fields; i++) {
608 MonoMarshalNative ntype;
609 MonoMarshalConv conv;
610 MonoType *ftype = info->fields [i].field->type;
613 gboolean last_field = i < (info->num_fields -1) ? 0 : 1;
615 if (ftype->attrs & FIELD_ATTRIBUTE_STATIC)
618 ntype = mono_type_to_unmanaged (ftype, info->fields [i].mspec, TRUE, klass->unicode, &conv);
621 msize = klass->instance_size - info->fields [i].field->offset;
622 usize = info->native_size - info->fields [i].offset;
624 msize = klass->fields [i + 1].offset - info->fields [i].field->offset;
625 usize = info->fields [i + 1].offset - info->fields [i].offset;
627 g_assert (msize > 0 && usize > 0);
630 case MONO_MARSHAL_CONV_NONE:
632 if (ftype->byref || ftype->type == MONO_TYPE_I ||
633 ftype->type == MONO_TYPE_U) {
634 mono_mb_emit_byte (mb, CEE_LDLOC_1);
635 mono_mb_emit_byte (mb, CEE_LDLOC_0);
636 mono_mb_emit_byte (mb, CEE_LDIND_I);
637 mono_mb_emit_byte (mb, CEE_STIND_I);
641 switch (ftype->type) {
644 mono_mb_emit_byte (mb, CEE_LDLOC_1);
645 mono_mb_emit_byte (mb, CEE_LDLOC_0);
646 mono_mb_emit_byte (mb, CEE_LDIND_I4);
647 mono_mb_emit_byte (mb, CEE_STIND_I4);
651 case MONO_TYPE_BOOLEAN:
652 mono_mb_emit_byte (mb, CEE_LDLOC_1);
653 mono_mb_emit_byte (mb, CEE_LDLOC_0);
654 mono_mb_emit_byte (mb, CEE_LDIND_I1);
655 mono_mb_emit_byte (mb, CEE_STIND_I1);
659 mono_mb_emit_byte (mb, CEE_LDLOC_1);
660 mono_mb_emit_byte (mb, CEE_LDLOC_0);
661 mono_mb_emit_byte (mb, CEE_LDIND_I2);
662 mono_mb_emit_byte (mb, CEE_STIND_I2);
666 mono_mb_emit_byte (mb, CEE_LDLOC_1);
667 mono_mb_emit_byte (mb, CEE_LDLOC_0);
668 mono_mb_emit_byte (mb, CEE_LDIND_I8);
669 mono_mb_emit_byte (mb, CEE_STIND_I8);
672 mono_mb_emit_byte (mb, CEE_LDLOC_1);
673 mono_mb_emit_byte (mb, CEE_LDLOC_0);
674 mono_mb_emit_byte (mb, CEE_LDIND_R4);
675 mono_mb_emit_byte (mb, CEE_STIND_R4);
678 mono_mb_emit_byte (mb, CEE_LDLOC_1);
679 mono_mb_emit_byte (mb, CEE_LDLOC_0);
680 mono_mb_emit_byte (mb, CEE_LDIND_R8);
681 mono_mb_emit_byte (mb, CEE_STIND_R8);
683 case MONO_TYPE_VALUETYPE:
684 emit_struct_conv (mb, ftype->data.klass, to_object);
687 g_error ("marshalling type %02x not implemented", ftype->type);
693 emit_ptr_to_str_conv (mb, ftype, conv, usize, msize);
695 emit_str_to_ptr_conv (mb, conv, usize, msize);
699 mono_mb_emit_add_to_local (mb, 0, usize);
700 mono_mb_emit_add_to_local (mb, 1, msize);
702 mono_mb_emit_add_to_local (mb, 0, msize);
703 mono_mb_emit_add_to_local (mb, 1, usize);
708 static MonoAsyncResult *
709 mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
711 MonoMethodMessage *msg;
712 MonoDelegate *async_callback;
716 MonoMethod *method = NULL;
721 klass = delegate->object.vtable->klass;
723 method = mono_get_delegate_invoke (klass);
724 for (i = 0; i < klass->method.count; ++i) {
725 if (klass->methods [i]->name[0] == 'B' &&
726 !strcmp ("BeginInvoke", klass->methods [i]->name)) {
727 method = klass->methods [i];
732 g_assert (method != NULL);
734 im = mono_get_delegate_invoke (method->klass);
736 msg = mono_method_call_message_new (method, params, im, &async_callback, &state);
738 return mono_thread_pool_add ((MonoObject *)delegate, msg, async_callback, state);
742 mono_mb_emit_save_args (MonoMethodBuilder *mb, MonoMethodSignature *sig, gboolean save_this)
744 int i, params_var, tmp_var;
746 /* allocate local (pointer) *params[] */
747 params_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
748 /* allocate local (pointer) tmp */
749 tmp_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
751 /* alloate space on stack to store an array of pointers to the arguments */
752 mono_mb_emit_icon (mb, sizeof (gpointer) * (sig->param_count + 1));
753 mono_mb_emit_byte (mb, CEE_PREFIX1);
754 mono_mb_emit_byte (mb, CEE_LOCALLOC);
755 mono_mb_emit_stloc (mb, params_var);
758 mono_mb_emit_ldloc (mb, params_var);
759 mono_mb_emit_stloc (mb, tmp_var);
761 if (save_this && sig->hasthis) {
762 mono_mb_emit_ldloc (mb, tmp_var);
763 mono_mb_emit_ldarg_addr (mb, 0);
764 mono_mb_emit_byte (mb, CEE_STIND_I);
765 /* tmp = tmp + sizeof (gpointer) */
766 if (sig->param_count)
767 mono_mb_emit_add_to_local (mb, tmp_var, sizeof (gpointer));
771 for (i = 0; i < sig->param_count; i++) {
772 mono_mb_emit_ldloc (mb, tmp_var);
773 mono_mb_emit_ldarg_addr (mb, i + sig->hasthis);
774 mono_mb_emit_byte (mb, CEE_STIND_I);
775 /* tmp = tmp + sizeof (gpointer) */
776 if (i < (sig->param_count - 1))
777 mono_mb_emit_add_to_local (mb, tmp_var, sizeof (gpointer));
784 mono_signature_to_name (MonoMethodSignature *sig, const char *prefix)
788 GString *res = g_string_new ("");
791 g_string_append (res, prefix);
792 g_string_append_c (res, '_');
795 mono_type_get_desc (res, sig->ret, FALSE);
797 for (i = 0; i < sig->param_count; ++i) {
798 g_string_append_c (res, '_');
799 mono_type_get_desc (res, sig->params [i], FALSE);
802 g_string_free (res, FALSE);
807 mono_marshal_get_delegate_begin_invoke (MonoMethod *method)
809 MonoMethodSignature *sig;
810 static MonoMethodSignature *csig = NULL;
811 MonoMethodBuilder *mb;
817 g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class &&
818 !strcmp (method->name, "BeginInvoke"));
820 sig = method->signature;
822 cache = method->klass->image->delegate_begin_invoke_cache;
823 if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
826 g_assert (sig->hasthis);
829 int sigsize = sizeof (MonoMethodSignature) + 2 * sizeof (MonoType *);
830 csig = g_malloc0 (sigsize);
832 /* MonoAsyncResult * begin_invoke (MonoDelegate *delegate, gpointer params[]) */
833 csig->param_count = 2;
834 csig->ret = &mono_defaults.object_class->byval_arg;
835 csig->params [0] = &mono_defaults.object_class->byval_arg;
836 csig->params [1] = &mono_defaults.int_class->byval_arg;
839 name = mono_signature_to_name (sig, "begin_invoke");
840 mb = mono_mb_new (mono_defaults.multicastdelegate_class, name);
843 mb->method->wrapper_type = MONO_WRAPPER_DELEGATE_BEGIN_INVOKE;
844 mb->method->save_lmf = 1;
846 params_var = mono_mb_emit_save_args (mb, sig, FALSE);
848 mono_mb_emit_ldarg (mb, 0);
849 mono_mb_emit_ldloc (mb, params_var);
850 mono_mb_emit_native_call (mb, csig, mono_delegate_begin_invoke);
851 mono_mb_emit_byte (mb, CEE_RET);
853 res = mono_mb_create_method (mb, sig, 0);
855 g_hash_table_insert (cache, sig, res);
860 mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
862 MonoDomain *domain = mono_domain_get ();
863 MonoAsyncResult *ares;
864 MonoMethod *method = NULL;
865 MonoMethodSignature *sig;
866 MonoMethodMessage *msg;
867 MonoObject *res, *exc;
874 if (!delegate->method_info || !delegate->method_info->method)
875 g_assert_not_reached ();
877 klass = delegate->object.vtable->klass;
879 for (i = 0; i < klass->method.count; ++i) {
880 if (klass->methods [i]->name[0] == 'E' &&
881 !strcmp ("EndInvoke", klass->methods [i]->name)) {
882 method = klass->methods [i];
887 g_assert (method != NULL);
889 sig = method->signature;
891 msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
893 ares = mono_array_get (msg->args, gpointer, sig->param_count - 1);
896 res = mono_thread_pool_finish (ares, &out_args, &exc);
899 char *strace = mono_string_to_utf8 (((MonoException*)exc)->stack_trace);
901 tmp = g_strdup_printf ("%s\nException Rethrown at:\n", strace);
903 ((MonoException*)exc)->stack_trace = mono_string_new (domain, tmp);
905 mono_raise_exception ((MonoException*)exc);
908 mono_method_return_message_restore (method, params, out_args);
913 mono_mb_emit_restore_result (MonoMethodBuilder *mb, MonoType *return_type)
915 if (return_type->byref)
916 return_type = &mono_defaults.int_class->byval_arg;
917 else if (return_type->type == MONO_TYPE_VALUETYPE && return_type->data.klass->enumtype)
918 return_type = return_type->data.klass->enum_basetype;
920 switch (return_type->type) {
922 g_assert_not_reached ();
924 case MONO_TYPE_STRING:
925 case MONO_TYPE_CLASS:
926 case MONO_TYPE_OBJECT:
927 case MONO_TYPE_ARRAY:
928 case MONO_TYPE_SZARRAY:
932 case MONO_TYPE_BOOLEAN:
933 mono_mb_emit_byte (mb, CEE_UNBOX);
934 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
935 mono_mb_emit_byte (mb, CEE_LDIND_U1);
938 mono_mb_emit_byte (mb, CEE_UNBOX);
939 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
940 mono_mb_emit_byte (mb, CEE_LDIND_I1);
944 mono_mb_emit_byte (mb, CEE_UNBOX);
945 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
946 mono_mb_emit_byte (mb, CEE_LDIND_U2);
949 mono_mb_emit_byte (mb, CEE_UNBOX);
950 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
951 mono_mb_emit_byte (mb, CEE_LDIND_I2);
953 #if SIZEOF_VOID_P == 4
957 mono_mb_emit_byte (mb, CEE_UNBOX);
958 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
959 mono_mb_emit_byte (mb, CEE_LDIND_I4);
961 #if SIZEOF_VOID_P == 4
965 mono_mb_emit_byte (mb, CEE_UNBOX);
966 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
967 mono_mb_emit_byte (mb, CEE_LDIND_U4);
971 mono_mb_emit_byte (mb, CEE_UNBOX);
972 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
973 mono_mb_emit_byte (mb, CEE_LDIND_I8);
976 mono_mb_emit_byte (mb, CEE_UNBOX);
977 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
978 mono_mb_emit_byte (mb, CEE_LDIND_R4);
981 mono_mb_emit_byte (mb, CEE_UNBOX);
982 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
983 mono_mb_emit_byte (mb, CEE_LDIND_R8);
985 case MONO_TYPE_VALUETYPE: {
987 mono_mb_emit_byte (mb, CEE_UNBOX);
988 class = mono_mb_add_data (mb, mono_class_from_mono_type (return_type));
989 mono_mb_emit_i4 (mb, class);
990 mono_mb_emit_byte (mb, CEE_LDOBJ);
991 mono_mb_emit_i4 (mb, class);
995 g_warning ("type 0x%x not handled", return_type->type);
996 g_assert_not_reached ();
999 mono_mb_emit_byte (mb, CEE_RET);
1003 mono_marshal_get_delegate_end_invoke (MonoMethod *method)
1005 MonoMethodSignature *sig;
1006 static MonoMethodSignature *csig = NULL;
1007 MonoMethodBuilder *mb;
1013 g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class &&
1014 !strcmp (method->name, "EndInvoke"));
1016 sig = method->signature;
1018 cache = method->klass->image->delegate_end_invoke_cache;
1019 if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
1022 g_assert (sig->hasthis);
1025 int sigsize = sizeof (MonoMethodSignature) + 2 * sizeof (MonoType *);
1026 csig = g_malloc0 (sigsize);
1028 /* MonoObject *end_invoke (MonoDelegate *delegate, gpointer params[]) */
1029 csig->param_count = 2;
1030 csig->ret = &mono_defaults.object_class->byval_arg;
1031 csig->params [0] = &mono_defaults.object_class->byval_arg;
1032 csig->params [1] = &mono_defaults.int_class->byval_arg;
1035 name = mono_signature_to_name (sig, "end_invoke");
1036 mb = mono_mb_new (mono_defaults.multicastdelegate_class, name);
1039 mb->method->wrapper_type = MONO_WRAPPER_DELEGATE_END_INVOKE;
1040 mb->method->save_lmf = 1;
1042 params_var = mono_mb_emit_save_args (mb, sig, FALSE);
1044 mono_mb_emit_ldarg (mb, 0);
1045 mono_mb_emit_ldloc (mb, params_var);
1046 mono_mb_emit_native_call (mb, csig, mono_delegate_end_invoke);
1048 if (sig->ret->type == MONO_TYPE_VOID)
1049 mono_mb_emit_byte (mb, CEE_POP);
1051 mono_mb_emit_restore_result (mb, sig->ret);
1053 res = mono_mb_create_method (mb, sig, 0);
1055 g_hash_table_insert (cache, sig, res);
1060 mono_remoting_wrapper (MonoMethod *method, gpointer *params)
1062 MonoMethodMessage *msg;
1063 MonoTransparentProxy *this;
1064 MonoObject *res, *exc;
1065 MonoArray *out_args;
1067 this = *((MonoTransparentProxy **)params [0]);
1070 g_assert (((MonoObject *)this)->vtable->klass == mono_defaults.transparent_proxy_class);
1072 /* skip the this pointer */
1075 msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
1077 res = mono_remoting_invoke ((MonoObject *)this->rp, msg, &exc, &out_args);
1080 mono_raise_exception ((MonoException *)exc);
1082 mono_method_return_message_restore (method, params, out_args);
1088 mono_marshal_get_remoting_invoke (MonoMethod *method)
1090 MonoMethodSignature *sig;
1091 static MonoMethodSignature *csig = NULL;
1092 MonoMethodBuilder *mb;
1099 if (method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE)
1102 sig = method->signature;
1104 /* we cant remote methods without this pointer */
1108 cache = method->klass->image->remoting_invoke_cache;
1109 if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
1113 int sigsize = sizeof (MonoMethodSignature) + 2 * sizeof (MonoType *);
1114 csig = g_malloc0 (sigsize);
1116 /* MonoObject *remoting_wrapper (MonoMethod *method, gpointer params[]) */
1117 csig->param_count = 2;
1118 csig->ret = &mono_defaults.object_class->byval_arg;
1119 csig->params [0] = &mono_defaults.int_class->byval_arg;
1120 csig->params [1] = &mono_defaults.int_class->byval_arg;
1123 mb = mono_mb_new (method->klass, method->name);
1124 mb->method->wrapper_type = MONO_WRAPPER_REMOTING_INVOKE;
1126 params_var = mono_mb_emit_save_args (mb, sig, TRUE);
1128 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1129 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
1130 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, method));
1131 mono_mb_emit_ldloc (mb, params_var);
1132 mono_mb_emit_native_call (mb, csig, mono_remoting_wrapper);
1134 if (sig->ret->type == MONO_TYPE_VOID)
1135 mono_mb_emit_byte (mb, CEE_POP);
1137 mono_mb_emit_restore_result (mb, sig->ret);
1139 res = mono_mb_create_method (mb, sig, 0);
1141 g_hash_table_insert (cache, method, res);
1146 * the returned method invokes all methods in a multicast delegate
1149 mono_marshal_get_delegate_invoke (MonoMethod *method)
1151 MonoMethodSignature *sig, *static_sig;
1153 MonoMethodBuilder *mb;
1159 g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class &&
1160 !strcmp (method->name, "Invoke"));
1162 sig = method->signature;
1164 cache = method->klass->image->delegate_invoke_cache;
1165 if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
1168 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1169 static_sig = g_memdup (sig, sigsize);
1170 static_sig->hasthis = 0;
1172 name = mono_signature_to_name (sig, "invoke");
1173 mb = mono_mb_new (mono_defaults.multicastdelegate_class, name);
1176 mb->method->wrapper_type = MONO_WRAPPER_DELEGATE_INVOKE;
1178 /* allocate local 0 (object) prev */
1179 mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1180 /* allocate local 1 (object) target */
1181 mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1182 /* allocate local 2 (pointer) mptr */
1183 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1185 /* allocate local 3 to store the return value */
1186 if (sig->ret->type != MONO_TYPE_VOID)
1187 mono_mb_add_local (mb, sig->ret);
1189 g_assert (sig->hasthis);
1191 /* prev = addr of delegate */
1192 mono_mb_emit_ldarg (mb, 0);
1193 mono_mb_emit_stloc (mb, 0);
1197 /* target = delegate->target */
1198 mono_mb_emit_ldloc (mb, 0);
1199 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1200 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
1201 mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoDelegate, target));
1202 mono_mb_emit_byte (mb, CEE_ADD);
1203 mono_mb_emit_byte (mb, CEE_LDIND_I);
1204 mono_mb_emit_stloc (mb, 1);
1206 /* mptr = delegate->method_ptr */
1207 mono_mb_emit_ldloc (mb, 0);
1208 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1209 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
1210 mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
1211 mono_mb_emit_byte (mb, CEE_ADD);
1212 mono_mb_emit_byte (mb, CEE_LDIND_I);
1213 mono_mb_emit_stloc (mb, 2);
1215 /* target == null ? */
1216 mono_mb_emit_ldloc (mb, 1);
1217 mono_mb_emit_byte (mb, CEE_BRTRUE);
1219 mono_mb_emit_i4 (mb, 0);
1221 /* emit static method call */
1223 for (i = 0; i < sig->param_count; i++)
1224 mono_mb_emit_ldarg (mb, i + 1);
1226 mono_mb_emit_ldloc (mb, 2);
1227 mono_mb_emit_byte (mb, CEE_CALLI);
1228 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, static_sig));
1230 if (sig->ret->type != MONO_TYPE_VOID)
1231 mono_mb_emit_stloc (mb, 3);
1233 mono_mb_emit_byte (mb, CEE_BR);
1235 mono_mb_emit_i4 (mb, 0);
1237 /* target != null, emit non static method call */
1239 mono_mb_patch_addr (mb, pos [1], mb->pos - (pos [1] + 4));
1240 mono_mb_emit_ldloc (mb, 1);
1242 for (i = 0; i < sig->param_count; i++)
1243 mono_mb_emit_ldarg (mb, i + 1);
1245 mono_mb_emit_ldloc (mb, 2);
1246 mono_mb_emit_byte (mb, CEE_CALLI);
1247 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, sig));
1249 if (sig->ret->type != MONO_TYPE_VOID)
1250 mono_mb_emit_stloc (mb, 3);
1252 mono_mb_patch_addr (mb, pos [2], mb->pos - (pos [2] + 4));
1254 /* prev = delegate->prev */
1255 mono_mb_emit_ldloc (mb, 0);
1256 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1257 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
1258 mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoMulticastDelegate, prev));
1259 mono_mb_emit_byte (mb, CEE_ADD);
1260 mono_mb_emit_byte (mb, CEE_LDIND_I);
1261 mono_mb_emit_stloc (mb, 0);
1263 /* if prev != null goto loop */
1264 mono_mb_emit_ldloc (mb, 0);
1265 mono_mb_emit_byte (mb, CEE_BRTRUE);
1266 mono_mb_emit_i4 (mb, pos [0] - (mb->pos + 4));
1268 if (sig->ret->type != MONO_TYPE_VOID)
1269 mono_mb_emit_ldloc (mb, 3);
1271 mono_mb_emit_byte (mb, CEE_RET);
1273 res = mono_mb_create_method (mb, sig, 0);
1276 g_hash_table_insert (cache, sig, res);
1282 * generates IL code for the runtime invoke function
1283 * MonoObject *runtime_invoke (MonoObject *this, void **params, MonoObject **exc)
1285 * we also catch exceptions if exc != null
1288 mono_marshal_get_runtime_invoke (MonoMethod *method)
1290 MonoMethodSignature *sig, *csig;
1291 MonoExceptionClause *clause;
1292 MonoMethodHeader *header;
1293 MonoMethodBuilder *mb;
1296 static MonoString *string_dummy = NULL;
1297 int i, pos, sigsize;
1301 cache = method->klass->image->runtime_invoke_cache;
1302 if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
1305 /* to make it work with our special string constructors */
1307 string_dummy = mono_string_new_wrapper ("dummy");
1309 sig = method->signature;
1311 sigsize = sizeof (MonoMethodSignature) + 3 * sizeof (MonoType *);
1312 csig = g_malloc0 (sigsize);
1314 csig->param_count = 3;
1315 csig->ret = &mono_defaults.object_class->byval_arg;
1316 csig->params [0] = &mono_defaults.object_class->byval_arg;
1317 csig->params [1] = &mono_defaults.int_class->byval_arg;
1318 csig->params [2] = &mono_defaults.int_class->byval_arg;
1320 mb = mono_mb_new (method->klass, method->name);
1321 mb->method->wrapper_type = MONO_WRAPPER_RUNTIME_INVOKE;
1323 /* allocate local 0 (object) tmp */
1324 mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1325 /* allocate local 1 (object) exc */
1326 mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1328 /* cond set *exc to null */
1329 mono_mb_emit_byte (mb, CEE_LDARG_2);
1330 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
1331 mono_mb_emit_byte (mb, 3);
1332 mono_mb_emit_byte (mb, CEE_LDARG_2);
1333 mono_mb_emit_byte (mb, CEE_LDNULL);
1334 mono_mb_emit_byte (mb, CEE_STIND_I);
1337 if (method->string_ctor) {
1338 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1339 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
1340 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, string_dummy));
1342 mono_mb_emit_ldarg (mb, 0);
1346 for (i = 0; i < sig->param_count; i++) {
1347 MonoType *t = sig->params [i];
1350 mono_mb_emit_ldarg (mb, 1);
1352 mono_mb_emit_icon (mb, sizeof (gpointer) * i);
1353 mono_mb_emit_byte (mb, CEE_ADD);
1355 mono_mb_emit_byte (mb, CEE_LDIND_I);
1360 type = sig->params [i]->type;
1364 mono_mb_emit_byte (mb, CEE_LDIND_I1);
1366 case MONO_TYPE_BOOLEAN:
1368 mono_mb_emit_byte (mb, CEE_LDIND_U1);
1371 mono_mb_emit_byte (mb, CEE_LDIND_I2);
1374 case MONO_TYPE_CHAR:
1375 mono_mb_emit_byte (mb, CEE_LDIND_U2);
1377 #if SIZEOF_VOID_P == 4
1381 mono_mb_emit_byte (mb, CEE_LDIND_I4);
1383 #if SIZEOF_VOID_P == 4
1387 mono_mb_emit_byte (mb, CEE_LDIND_U4);
1390 mono_mb_emit_byte (mb, CEE_LDIND_R4);
1393 mono_mb_emit_byte (mb, CEE_LDIND_R8);
1395 #if SIZEOF_VOID_P == 8
1401 mono_mb_emit_byte (mb, CEE_LDIND_I8);
1403 case MONO_TYPE_STRING:
1404 case MONO_TYPE_CLASS:
1405 case MONO_TYPE_ARRAY:
1407 case MONO_TYPE_SZARRAY:
1408 case MONO_TYPE_OBJECT:
1411 case MONO_TYPE_VALUETYPE:
1412 if (t->data.klass->enumtype) {
1413 type = t->data.klass->enum_basetype->type;
1416 g_assert_not_reached ();
1419 g_assert_not_reached ();
1423 if (method->string_ctor) {
1424 MonoMethodSignature *strsig;
1426 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1427 strsig = g_memdup (sig, sigsize);
1428 strsig->ret = &mono_defaults.string_class->byval_arg;
1430 mono_mb_emit_managed_call (mb, method, strsig);
1432 mono_mb_emit_managed_call (mb, method, NULL);
1434 switch (sig->ret->type) {
1435 case MONO_TYPE_VOID:
1436 if (!method->string_ctor)
1437 mono_mb_emit_byte (mb, CEE_LDNULL);
1451 case MONO_TYPE_VALUETYPE:
1452 /* box value types */
1453 mono_mb_emit_byte (mb, CEE_BOX);
1454 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (sig->ret)));
1456 case MONO_TYPE_STRING:
1457 case MONO_TYPE_CLASS:
1458 case MONO_TYPE_ARRAY:
1459 case MONO_TYPE_SZARRAY:
1460 case MONO_TYPE_OBJECT:
1465 g_assert_not_reached ();
1468 mono_mb_emit_stloc (mb, 0);
1470 mono_mb_emit_byte (mb, CEE_LEAVE);
1472 mono_mb_emit_i4 (mb, 0);
1474 /* fixme: use a filter clause and only catch exceptions
1475 * when exc != null. With RETHROW we get wrong stack
1477 clause = g_new0 (MonoExceptionClause, 1);
1478 clause->flags = MONO_EXCEPTION_CLAUSE_NONE;
1479 clause->try_offset = 0;
1480 clause->try_len = mb->pos;
1481 clause->handler_offset = mb->pos;
1485 /* store exception */
1486 mono_mb_emit_stloc (mb, 1);
1488 mono_mb_emit_byte (mb, CEE_LDARG_2);
1489 mono_mb_emit_byte (mb, CEE_BRTRUE_S);
1490 mono_mb_emit_byte (mb, 2);
1491 mono_mb_emit_byte (mb, CEE_PREFIX1);
1492 mono_mb_emit_byte (mb, CEE_RETHROW);
1494 mono_mb_emit_byte (mb, CEE_LDARG_2);
1495 mono_mb_emit_ldloc (mb, 1);
1496 mono_mb_emit_byte (mb, CEE_STIND_I);
1498 mono_mb_emit_byte (mb, CEE_LEAVE);
1499 mono_mb_emit_i4 (mb, 0);
1501 clause->handler_len = mb->pos - clause->handler_offset;
1504 mono_mb_patch_addr (mb, pos, mb->pos - (pos + 4));
1505 mono_mb_emit_ldloc (mb, 0);
1506 mono_mb_emit_byte (mb, CEE_RET);
1508 res = mono_mb_create_method (mb, csig, 0);
1511 header = ((MonoMethodNormal *)res)->header;
1512 header->num_clauses = 1;
1513 header->clauses = clause;
1515 g_hash_table_insert (cache, method, res);
1521 * generates IL code to call managed methods from unmanaged code
1524 mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this)
1526 MonoMethodSignature *sig, *csig;
1527 MonoMethodBuilder *mb;
1531 int i, sigsize, *tmp_locals;
1533 g_assert (method != NULL);
1535 cache = method->klass->image->managed_wrapper_cache;
1536 if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
1539 sig = method->signature;
1541 mb = mono_mb_new (method->klass, method->name);
1542 mb->method->wrapper_type = MONO_WRAPPER_NATIVE_TO_MANAGED;
1544 /* allocate local 0 (pointer) src_ptr */
1545 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1546 /* allocate local 1 (pointer) dst_ptr */
1547 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1548 /* allocate local 2 (boolean) delete_old */
1549 mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
1551 mono_mb_emit_byte (mb, CEE_LDNULL);
1552 mono_mb_emit_byte (mb, CEE_STLOC_2);
1554 /* we copy the signature, so that we can modify it */
1555 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1556 csig = g_memdup (sig, sigsize);
1560 /* fixme: howto handle this ? */
1564 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1565 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
1566 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, this));
1571 g_assert_not_reached ();
1576 /* we first do all conversions */
1577 tmp_locals = alloca (sizeof (int) * sig->param_count);
1578 for (i = 0; i < sig->param_count; i ++) {
1579 MonoType *t = sig->params [i];
1584 case MONO_TYPE_VALUETYPE:
1586 klass = sig->params [i]->data.klass;
1587 if (klass->enumtype)
1590 tmp_locals [i] = mono_mb_add_local (mb, &klass->byval_arg);
1592 mono_mb_emit_ldarg_addr (mb, i);
1593 mono_mb_emit_byte (mb, CEE_STLOC_0);
1594 mono_mb_emit_ldloc_addr (mb, tmp_locals [i]);
1595 mono_mb_emit_byte (mb, CEE_STLOC_1);
1597 /* emit valuetype convnversion code code */
1598 emit_struct_conv (mb, klass, TRUE);
1600 case MONO_TYPE_STRING:
1602 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1604 csig->params [i] = &mono_defaults.int_class->byval_arg;
1605 mono_mb_emit_ldarg (mb, i);
1606 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1607 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
1608 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
1609 mono_mb_emit_stloc (mb, tmp_locals [i]);
1615 for (i = 0; i < sig->param_count; i++) {
1616 MonoType *t = sig->params [i];
1620 g_assert_not_reached ();
1637 mono_mb_emit_ldarg (mb, i);
1639 case MONO_TYPE_STRING:
1640 g_assert (tmp_locals [i]);
1641 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1643 case MONO_TYPE_CLASS:
1644 case MONO_TYPE_ARRAY:
1645 case MONO_TYPE_SZARRAY:
1646 case MONO_TYPE_OBJECT:
1647 /* fixme: conversions ? */
1648 mono_mb_emit_ldarg (mb, i);
1650 case MONO_TYPE_VALUETYPE:
1651 klass = sig->params [i]->data.klass;
1652 if (klass->enumtype) {
1653 mono_mb_emit_ldarg (mb, i);
1657 g_assert (tmp_locals [i]);
1658 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1661 g_warning ("type 0x%02x unknown", t->type);
1662 g_assert_not_reached ();
1666 mono_mb_emit_managed_call (mb, method, NULL);
1668 /* fixme: add return type conversions */
1670 mono_mb_emit_byte (mb, CEE_RET);
1672 res = mono_mb_create_method (mb, csig, 0);
1675 g_hash_table_insert (cache, method, res);
1681 * generates IL code for the pinvoke wrapper (the generated method
1682 * calls the unamnage code in method->addr)
1685 mono_marshal_get_native_wrapper (MonoMethod *method)
1687 MonoMethodSignature *sig, *csig;
1688 MonoMethodBuilder *mb;
1692 gboolean pinvoke = FALSE;
1693 int i, argnum, *tmp_locals;
1696 g_assert (method != NULL);
1698 cache = method->klass->image->native_wrapper_cache;
1699 if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
1702 sig = method->signature;
1704 if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
1705 (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
1708 mb = mono_mb_new (method->klass, method->name);
1709 mb->method->wrapper_type = MONO_WRAPPER_MANAGED_TO_NATIVE;
1711 mb->method->save_lmf = 1;
1713 if (pinvoke && !method->addr)
1714 mono_lookup_pinvoke_call (method);
1716 if (!method->addr) {
1717 mono_mb_emit_exception (mb);
1718 res = mono_mb_create_method (mb, sig, 0);
1720 g_hash_table_insert (cache, method, res);
1724 /* we copy the signature, so that we can modify it */
1725 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1726 csig = g_memdup (sig, sigsize);
1728 /* internal calls: we simply push all arguments and call the method (no conversions) */
1729 if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
1731 /* hack - string constructors returns a value */
1732 if (method->string_ctor)
1733 csig->ret = &mono_defaults.string_class->byval_arg;
1736 mono_mb_emit_byte (mb, CEE_LDARG_0);
1738 for (i = 0; i < sig->param_count; i++)
1739 mono_mb_emit_ldarg (mb, i + sig->hasthis);
1741 g_assert (method->addr);
1742 mono_mb_emit_native_call (mb, csig, method->addr);
1744 mono_mb_emit_byte (mb, CEE_RET);
1746 res = mono_mb_create_method (mb, csig, 0);
1748 g_hash_table_insert (cache, method, res);
1754 /* pinvoke: we need to convert the arguments if necessary */
1758 /* we allocate local for use with emit_struct_conv() */
1759 /* allocate local 0 (pointer) src_ptr */
1760 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1761 /* allocate local 1 (pointer) dst_ptr */
1762 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1763 /* allocate local 2 (boolean) delete_old */
1764 mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
1766 mono_mb_emit_icon (mb, 0);
1767 mono_mb_emit_byte (mb, CEE_STLOC_2);
1769 if (sig->ret->type != MONO_TYPE_VOID) {
1770 /* allocate local 3 to store the return value */
1771 mono_mb_add_local (mb, sig->ret);
1774 /* we first do all conversions */
1775 tmp_locals = alloca (sizeof (int) * sig->param_count);
1776 for (i = 0; i < sig->param_count; i ++) {
1777 MonoType *t = sig->params [i];
1779 argnum = i + sig->hasthis;
1783 /* fixme: what to do here? */
1788 case MONO_TYPE_VALUETYPE:
1790 klass = sig->params [i]->data.klass;
1791 if (klass->enumtype)
1794 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1796 /* store the address of the source into local variable 0 */
1797 mono_mb_emit_ldarg_addr (mb, argnum);
1798 mono_mb_emit_byte (mb, CEE_STLOC_0);
1800 /* allocate space for the native struct and
1801 * store the address into local variable 1 (dest) */
1802 mono_mb_emit_icon (mb, mono_class_native_size (klass));
1803 mono_mb_emit_byte (mb, CEE_PREFIX1);
1804 mono_mb_emit_byte (mb, CEE_LOCALLOC);
1805 mono_mb_emit_stloc (mb, tmp_locals [i]);
1807 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1808 mono_mb_emit_byte (mb, CEE_STLOC_1);
1810 /* emit valuetype convnversion code code */
1811 emit_struct_conv (mb, klass, FALSE);
1813 case MONO_TYPE_STRING:
1814 csig->params [argnum] = &mono_defaults.int_class->byval_arg;
1815 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1817 mono_mb_emit_ldarg (mb, argnum);
1818 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1819 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
1820 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPSTR);
1821 mono_mb_emit_stloc (mb, tmp_locals [i]);
1823 case MONO_TYPE_CLASS:
1824 case MONO_TYPE_OBJECT:
1825 csig->params [argnum] = &mono_defaults.int_class->byval_arg;
1826 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1828 if (t->data.klass->delegate) {
1829 mono_mb_emit_ldarg (mb, argnum);
1830 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1831 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
1832 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_DEL_FTN);
1833 mono_mb_emit_stloc (mb, tmp_locals [i]);
1835 mono_mb_emit_ldarg (mb, argnum);
1836 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1837 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
1838 /* fixme: convert to what ? */
1839 mono_mb_emit_stloc (mb, tmp_locals [i]);
1842 case MONO_TYPE_ARRAY:
1843 case MONO_TYPE_SZARRAY:
1844 csig->params [argnum] = &mono_defaults.int_class->byval_arg;
1845 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1847 mono_mb_emit_ldarg (mb, argnum);
1848 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1849 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
1850 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_ARRAY_LPARRAY);
1851 mono_mb_emit_stloc (mb, tmp_locals [i]);
1856 /* push all arguments */
1859 mono_mb_emit_byte (mb, CEE_LDARG_0);
1861 for (i = 0; i < sig->param_count; i++) {
1862 MonoType *t = sig->params [i];
1864 argnum = i + sig->hasthis;
1868 mono_mb_emit_ldarg (mb, argnum);
1873 case MONO_TYPE_BOOLEAN:
1874 mono_mb_emit_ldarg (mb, argnum);
1889 mono_mb_emit_ldarg (mb, argnum);
1891 case MONO_TYPE_VALUETYPE:
1892 klass = sig->params [i]->data.klass;
1893 if (klass->enumtype) {
1894 mono_mb_emit_ldarg (mb, argnum);
1897 g_assert (tmp_locals [i]);
1898 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1899 mono_mb_emit_byte (mb, CEE_LDOBJ);
1900 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, klass));
1902 case MONO_TYPE_STRING:
1903 /* fixme: load the address instead */
1904 g_assert (tmp_locals [i]);
1905 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1907 case MONO_TYPE_CLASS:
1908 case MONO_TYPE_OBJECT:
1909 g_assert (tmp_locals [i]);
1910 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1912 case MONO_TYPE_CHAR:
1913 /* fixme: dont know how to marshal that. We cant simply
1914 * convert it to a one byte UTF8 character, because an
1915 * unicode character may need more that one byte in UTF8 */
1916 mono_mb_emit_ldarg (mb, argnum);
1918 case MONO_TYPE_ARRAY:
1919 case MONO_TYPE_SZARRAY:
1920 g_assert (tmp_locals [i]);
1921 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1923 case MONO_TYPE_TYPEDBYREF:
1924 case MONO_TYPE_FNPTR:
1926 g_warning ("type 0x%02x unknown", t->type);
1927 g_assert_not_reached ();
1931 /* call the native method */
1932 mono_mb_emit_native_call (mb, csig, method->addr);
1934 /* return the result */
1936 if (!sig->ret->byref) {
1937 type = sig->ret->type;
1940 case MONO_TYPE_VOID:
1954 /* no conversions necessary */
1956 case MONO_TYPE_BOOLEAN:
1957 /* maybe we need to make sure that it fits within 8 bits */
1959 case MONO_TYPE_VALUETYPE:
1960 if (sig->ret->data.klass->enumtype) {
1961 type = sig->ret->data.klass->enum_basetype->type;
1964 g_warning ("generic valutype %s not handled",
1965 sig->ret->data.klass->name);
1966 g_assert_not_reached ();
1969 case MONO_TYPE_STRING:
1970 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1971 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
1972 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
1974 case MONO_TYPE_ARRAY:
1975 case MONO_TYPE_SZARRAY:
1976 case MONO_TYPE_CLASS:
1977 case MONO_TYPE_OBJECT:
1978 /* fixme: we need conversions here */
1980 case MONO_TYPE_CHAR:
1981 /* fixme: we need conversions here */
1983 case MONO_TYPE_TYPEDBYREF:
1984 case MONO_TYPE_FNPTR:
1986 g_warning ("return type 0x%02x unknown", sig->ret->type);
1987 g_assert_not_reached ();
1991 mono_mb_emit_byte (mb, CEE_RET);
1993 res = mono_mb_create_method (mb, sig, 0);
1996 g_hash_table_insert (cache, method, res);
2002 * generates IL code for StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld)
2005 mono_marshal_get_struct_to_ptr (MonoClass *klass)
2007 MonoMethodBuilder *mb;
2008 static MonoMethod *stoptr = NULL;
2011 g_assert (klass != NULL);
2013 if (klass->str_to_ptr)
2014 return klass->str_to_ptr;
2017 stoptr = mono_find_method_by_name (mono_defaults.marshal_class, "StructureToPtr", 3);
2020 mb = mono_mb_new (stoptr->klass, stoptr->name);
2022 /* allocate local 0 (pointer) src_ptr */
2023 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2024 /* allocate local 1 (pointer) dst_ptr */
2025 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2026 /* allocate local 2 (boolean) delete_old */
2027 mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
2028 mono_mb_emit_byte (mb, CEE_LDARG_2);
2029 mono_mb_emit_byte (mb, CEE_STLOC_2);
2031 /* initialize src_ptr to point to the start of object data */
2032 mono_mb_emit_byte (mb, CEE_LDARG_0);
2033 mono_mb_emit_icon (mb, sizeof (MonoObject));
2034 mono_mb_emit_byte (mb, CEE_ADD);
2035 mono_mb_emit_byte (mb, CEE_STLOC_0);
2037 /* initialize dst_ptr */
2038 mono_mb_emit_byte (mb, CEE_LDARG_1);
2039 mono_mb_emit_byte (mb, CEE_STLOC_1);
2041 emit_struct_conv (mb, klass, FALSE);
2043 mono_mb_emit_byte (mb, CEE_RET);
2045 res = mono_mb_create_method (mb, stoptr->signature, 0);
2048 klass->str_to_ptr = res;
2053 * generates IL code for PtrToStructure (IntPtr src, object structure)
2056 mono_marshal_get_ptr_to_struct (MonoClass *klass)
2058 MonoMethodBuilder *mb;
2059 static MonoMethod *ptostr = NULL;
2062 g_assert (klass != NULL);
2064 if (klass->ptr_to_str)
2065 return klass->ptr_to_str;
2068 ptostr = mono_find_method_by_name (mono_defaults.marshal_class, "PtrToStructure", 2);
2071 mb = mono_mb_new (ptostr->klass, ptostr->name);
2073 /* allocate local 0 (pointer) src_ptr */
2074 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2075 /* allocate local 1 (pointer) dst_ptr */
2076 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2077 /* allocate local 2 (boolean) delete_old */
2078 mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
2080 mono_mb_emit_byte (mb, CEE_LDNULL);
2081 mono_mb_emit_byte (mb, CEE_STLOC_2);
2083 /* initialize src_ptr to point to the start of object data */
2084 mono_mb_emit_byte (mb, CEE_LDARG_0);
2085 mono_mb_emit_byte (mb, CEE_STLOC_0);
2087 /* initialize dst_ptr */
2088 mono_mb_emit_byte (mb, CEE_LDARG_1);
2089 mono_mb_emit_icon (mb, sizeof (MonoObject));
2090 mono_mb_emit_byte (mb, CEE_ADD);
2091 mono_mb_emit_byte (mb, CEE_STLOC_1);
2093 emit_struct_conv (mb, klass, TRUE);
2095 mono_mb_emit_byte (mb, CEE_RET);
2097 res = mono_mb_create_method (mb, ptostr->signature, 0);
2100 klass->ptr_to_str = res;
2104 /* FIXME: on win32 we should probably use GlobalAlloc(). */
2106 mono_marshal_alloc (gpointer size) {
2107 return g_try_malloc ((gulong)size);
2111 mono_marshal_free (gpointer ptr) {
2116 mono_marshal_realloc (gpointer ptr, gpointer size) {
2117 return g_try_realloc (ptr, (gulong)size);
2121 mono_marshal_string_array (MonoArray *array)
2129 len = mono_array_length (array);
2131 result = g_malloc (sizeof (char*) * len);
2132 for (i = 0; i < len; ++i) {
2133 MonoString *s = (MonoString*)mono_array_get (array, gpointer, i);
2134 result [i] = s ? mono_string_to_utf8 (s): NULL;
2140 ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged (MonoArray *src, gint32 start_index,
2141 gpointer dest, gint32 length)
2146 MONO_CHECK_ARG_NULL (src);
2147 MONO_CHECK_ARG_NULL (dest);
2149 g_assert (src->obj.vtable->klass->rank == 1);
2150 g_assert (start_index >= 0 && start_index < mono_array_length (src));
2151 g_assert (start_index + length <= mono_array_length (src));
2153 element_size = mono_array_element_size (src->obj.vtable->klass);
2155 source_addr = mono_array_addr_with_size (src, element_size, start_index);
2157 memcpy (dest, source_addr, length * element_size);
2161 ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged (gpointer src, gint32 start_index,
2162 MonoArray *dest, gint32 length)
2167 MONO_CHECK_ARG_NULL (src);
2168 MONO_CHECK_ARG_NULL (dest);
2170 g_assert (dest->obj.vtable->klass->rank == 1);
2171 g_assert (start_index >= 0 && start_index < mono_array_length (dest));
2172 g_assert (start_index + length <= mono_array_length (dest));
2174 element_size = mono_array_element_size (dest->obj.vtable->klass);
2176 dest_addr = mono_array_addr_with_size (dest, element_size, start_index);
2178 memcpy (dest_addr, src, length * element_size);
2182 ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr (gpointer ptr, gint32 offset)
2185 return *(gpointer*)(p + offset);
2189 ves_icall_System_Runtime_InteropServices_Marshal_ReadByte (gpointer ptr, gint32 offset)
2192 return *(unsigned char*)(p + offset);
2196 ves_icall_System_Runtime_InteropServices_Marshal_ReadInt16 (gpointer ptr, gint32 offset)
2199 return *(gint16*)(p + offset);
2203 ves_icall_System_Runtime_InteropServices_Marshal_ReadInt32 (gpointer ptr, gint32 offset)
2206 return *(gint32*)(p + offset);
2210 ves_icall_System_Runtime_InteropServices_Marshal_ReadInt64 (gpointer ptr, gint32 offset)
2213 return *(gint64*)(p + offset);
2217 ves_icall_System_Runtime_InteropServices_Marshal_WriteByte (gpointer ptr, gint32 offset, unsigned char val)
2220 *(unsigned char*)(p + offset) = val;
2224 ves_icall_System_Runtime_InteropServices_Marshal_WriteIntPtr (gpointer ptr, gint32 offset, gpointer val)
2227 *(gpointer*)(p + offset) = val;
2231 ves_icall_System_Runtime_InteropServices_Marshal_WriteInt16 (gpointer ptr, gint32 offset, gint16 val)
2234 *(gint16*)(p + offset) = val;
2238 ves_icall_System_Runtime_InteropServices_Marshal_WriteInt32 (gpointer ptr, gint32 offset, gint32 val)
2241 *(gint32*)(p + offset) = val;
2245 ves_icall_System_Runtime_InteropServices_Marshal_WriteInt64 (gpointer ptr, gint32 offset, gint64 val)
2248 *(gint64*)(p + offset) = val;
2252 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi (char *ptr)
2254 return mono_string_new (mono_domain_get (), ptr);
2258 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len (char *ptr, gint32 len)
2260 return mono_string_new_len (mono_domain_get (), ptr, len);
2264 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni (guint16 *ptr)
2266 MonoDomain *domain = mono_domain_get ();
2273 return mono_string_new_utf16 (domain, ptr, len);
2277 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len (guint16 *ptr, gint32 len)
2279 MonoDomain *domain = mono_domain_get ();
2281 return mono_string_new_utf16 (domain, ptr, len);
2285 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
2287 g_warning ("PtrToStringBSTR not implemented");
2288 g_assert_not_reached ();
2294 ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error (void)
2296 return (GetLastError ());
2300 ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionType *rtype)
2304 MONO_CHECK_ARG_NULL (rtype);
2306 klass = mono_class_from_mono_type (rtype->type);
2308 return mono_class_native_size (klass);
2312 ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr (MonoObject *obj, gpointer dst, MonoBoolean delete_old)
2317 MONO_CHECK_ARG_NULL (obj);
2318 MONO_CHECK_ARG_NULL (dst);
2320 method = mono_marshal_get_struct_to_ptr (obj->vtable->klass);
2324 pa [2] = &delete_old;
2326 mono_runtime_invoke (method, NULL, pa, NULL);
2330 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (gpointer src, MonoObject *dst)
2335 MONO_CHECK_ARG_NULL (src);
2336 MONO_CHECK_ARG_NULL (dst);
2338 method = mono_marshal_get_ptr_to_struct (dst->vtable->klass);
2343 mono_runtime_invoke (method, NULL, pa, NULL);
2347 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type (gpointer src, MonoReflectionType *type)
2349 MonoDomain *domain = mono_domain_get ();
2353 MONO_CHECK_ARG_NULL (src);
2354 MONO_CHECK_ARG_NULL (type);
2356 res = mono_object_new (domain, mono_class_from_mono_type (type->type));
2358 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (src, res);