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"
22 //#define DEBUG_RUNTIME_CODE
24 #define OPDEF(a,b,c,d,e,f,g,h,i,j) \
28 #include "mono/cil/opcode.def"
33 struct _MonoMethodBuilder {
37 guint32 code_size, pos;
42 emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object);
44 #ifdef DEBUG_RUNTIME_CODE
46 indenter (MonoDisHelper *dh, MonoMethod *method, guint32 ip_offset)
48 return g_strdup (" ");
51 static MonoDisHelper marshal_dh = {
62 mono_delegate_to_ftnptr (MonoDelegate *delegate)
64 MonoMethod *method, *wrapper;
70 if (delegate->delegate_trampoline)
71 return delegate->delegate_trampoline;
73 klass = ((MonoObject *)delegate)->vtable->klass;
74 g_assert (klass->delegate);
76 method = delegate->method_info->method;
77 wrapper = mono_marshal_get_managed_wrapper (method, delegate->target);
79 delegate->delegate_trampoline = mono_compile_method (wrapper);
81 return delegate->delegate_trampoline;
85 mono_array_to_savearray (MonoArray *array)
90 g_assert_not_reached ();
95 mono_array_to_lparray (MonoArray *array)
100 /* fixme: maybe we need to make a copy */
101 return array->vector;
105 mono_string_utf8_to_builder (MonoStringBuilder *sb, char *text)
107 GError *error = NULL;
117 ut = g_utf8_to_utf16 (text, l, NULL, &items_written, &error);
119 if (items_written > sb->capacity)
120 items_written = sb->capacity;
123 memcpy (sb->chars->vector, ut, items_written * 2);
124 sb->length = items_written;
126 g_error_free (error);
132 mono_string_builder_to_utf8 (MonoStringBuilder *sb)
139 res = g_malloc (sb->capacity + 1);
141 /* fixme: copy the content of the string builder? */
148 mono_string_to_ansibstr (MonoString *string_obj)
150 g_error ("implement me");
155 mono_string_to_bstr (MonoString *string_obj)
157 g_error ("implement me");
162 mono_string_to_byvalstr (gpointer dst, MonoString *src, int size)
167 g_assert (dst != NULL);
171 memset (dst, 0, size);
175 s = mono_string_to_utf8 (src);
176 len = MIN (size, strlen (s));
177 memcpy (dst, s, len);
180 *((char *)dst + size - 1) = 0;
184 mono_string_to_byvalwstr (gpointer dst, MonoString *src, int size)
188 g_assert (dst != NULL);
192 memset (dst, 0, size);
196 len = MIN (size, (mono_string_length (src) * 2));
197 memcpy (dst, mono_string_chars (src), len);
199 *((char *)dst + size - 1) = 0;
200 *((char *)dst + size - 2) = 0;
205 mono_find_method_by_name (MonoClass *klass, const char *name, int param_count)
207 MonoMethod *res = NULL;
210 for (i = 0; i < klass->method.count; ++i) {
211 if ((klass->methods [i]->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
212 klass->methods [i]->name[0] == name [0] &&
213 !strcmp (name, klass->methods [i]->name) &&
214 klass->methods [i]->signature->param_count == param_count) {
215 res = klass->methods [i];
223 mono_mb_free (MonoMethodBuilder *mb)
225 g_list_free (mb->locals_list);
230 mono_mb_new (MonoClass *klass, const char *name, MonoWrapperType type)
232 MonoMethodBuilder *mb;
235 g_assert (klass != NULL);
236 g_assert (name != NULL);
238 mb = g_new0 (MonoMethodBuilder, 1);
240 mb->method = m = (MonoMethod *)g_new0 (MonoMethodWrapper, 1);
243 m->name = g_strdup (name);
245 m->inline_count = -1;
246 m->wrapper_type = type;
249 mb->code = g_malloc (mb->code_size);
255 mono_mb_add_local (MonoMethodBuilder *mb, MonoType *type)
257 int res = mb->locals;
259 g_assert (mb != NULL);
260 g_assert (type != NULL);
262 mb->locals_list = g_list_append (mb->locals_list, type);
269 mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack)
271 MonoMethodHeader *header;
275 g_assert (mb != NULL);
277 ((MonoMethodNormal *)mb->method)->header = header = (MonoMethodHeader *)
278 g_malloc0 (sizeof (MonoMethodHeader) + mb->locals * sizeof (MonoType *));
283 header->max_stack = max_stack;
285 for (i = 0, l = mb->locals_list; l; l = l->next, i++) {
286 header->locals [i] = (MonoType *)l->data;
289 mb->method->signature = signature;
290 header->code = mb->code;
291 header->code_size = mb->pos;
292 header->num_locals = mb->locals;
294 #ifdef DEBUG_RUNTIME_CODE
295 printf ("RUNTIME CODE FOR %s\n", mono_method_full_name (mb->method, TRUE));
296 printf ("%s\n", mono_disasm_code (&marshal_dh, mb->method, mb->code, mb->code + mb->pos));
303 mono_mb_add_data (MonoMethodBuilder *mb, gpointer data)
305 MonoMethodWrapper *mw;
307 g_assert (mb != NULL);
309 mw = (MonoMethodWrapper *)mb->method;
311 mw->data = g_list_append (mw->data, data);
313 return g_list_length (mw->data);
317 mono_mb_patch_addr (MonoMethodBuilder *mb, int pos, int value)
319 mb->code [pos] = value & 0xff;
320 mb->code [pos + 1] = (value >> 8) & 0xff;
321 mb->code [pos + 2] = (value >> 16) & 0xff;
322 mb->code [pos + 3] = (value >> 24) & 0xff;
326 mono_mb_patch_addr_s (MonoMethodBuilder *mb, int pos, gint8 value)
328 *((gint8 *)(&mb->code [pos])) = value;
332 mono_mb_emit_byte (MonoMethodBuilder *mb, guint8 op)
334 if (mb->pos >= mb->code_size) {
336 mb->code = g_realloc (mb->code, mb->code_size);
339 mb->code [mb->pos++] = op;
343 mono_mb_emit_ldflda (MonoMethodBuilder *mb, gint32 offset)
345 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
346 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
347 mono_mb_emit_icon (mb, offset);
348 mono_mb_emit_byte (mb, CEE_ADD);
352 mono_mb_emit_i4 (MonoMethodBuilder *mb, gint32 data)
354 if ((mb->pos + 4) >= mb->code_size) {
356 mb->code = g_realloc (mb->code, mb->code_size);
359 mono_mb_patch_addr (mb, mb->pos, data);
364 mono_mb_emit_i2 (MonoMethodBuilder *mb, gint16 data)
366 if ((mb->pos + 2) >= mb->code_size) {
368 mb->code = g_realloc (mb->code, mb->code_size);
371 mb->code [mb->pos] = data & 0xff;
372 mb->code [mb->pos + 1] = (data >> 8) & 0xff;
377 mono_mb_emit_ldarg (MonoMethodBuilder *mb, guint argnum)
380 mono_mb_emit_byte (mb, CEE_LDARG_0 + argnum);
381 } else if (argnum < 256) {
382 mono_mb_emit_byte (mb, CEE_LDARG_S);
383 mono_mb_emit_byte (mb, argnum);
385 mono_mb_emit_byte (mb, CEE_PREFIX1);
386 mono_mb_emit_byte (mb, CEE_LDARG);
387 mono_mb_emit_i2 (mb, argnum);
392 mono_mb_emit_ldarg_addr (MonoMethodBuilder *mb, guint argnum)
395 mono_mb_emit_byte (mb, CEE_LDARGA_S);
396 mono_mb_emit_byte (mb, argnum);
398 mono_mb_emit_byte (mb, CEE_PREFIX1);
399 mono_mb_emit_byte (mb, CEE_LDARGA);
400 mono_mb_emit_i2 (mb, argnum);
405 mono_mb_emit_ldloc_addr (MonoMethodBuilder *mb, guint locnum)
408 mono_mb_emit_byte (mb, CEE_LDLOCA_S);
409 mono_mb_emit_byte (mb, locnum);
411 mono_mb_emit_byte (mb, CEE_PREFIX1);
412 mono_mb_emit_byte (mb, CEE_LDLOCA);
413 mono_mb_emit_i2 (mb, locnum);
418 mono_mb_emit_ldloc (MonoMethodBuilder *mb, guint num)
421 mono_mb_emit_byte (mb, CEE_LDLOC_0 + num);
422 } else if (num < 256) {
423 mono_mb_emit_byte (mb, CEE_LDLOC_S);
424 mono_mb_emit_byte (mb, num);
426 mono_mb_emit_byte (mb, CEE_PREFIX1);
427 mono_mb_emit_byte (mb, CEE_LDLOC);
428 mono_mb_emit_i2 (mb, num);
433 mono_mb_emit_stloc (MonoMethodBuilder *mb, guint num)
436 mono_mb_emit_byte (mb, CEE_STLOC_0 + num);
437 } else if (num < 256) {
438 mono_mb_emit_byte (mb, CEE_STLOC_S);
439 mono_mb_emit_byte (mb, num);
441 mono_mb_emit_byte (mb, CEE_PREFIX1);
442 mono_mb_emit_byte (mb, CEE_STLOC);
443 mono_mb_emit_i2 (mb, num);
448 mono_mb_emit_icon (MonoMethodBuilder *mb, gint32 value)
450 if (value >= -1 && value < 8) {
451 mono_mb_emit_byte (mb, CEE_LDC_I4_0 + value);
452 } else if (value >= -128 && value <= 127) {
453 mono_mb_emit_byte (mb, CEE_LDC_I4_S);
454 mono_mb_emit_byte (mb, value);
456 mono_mb_emit_byte (mb, CEE_LDC_I4);
457 mono_mb_emit_i4 (mb, value);
462 mono_mb_emit_managed_call (MonoMethodBuilder *mb, MonoMethod *method, MonoMethodSignature *opt_sig)
465 opt_sig = method->signature;
466 mono_mb_emit_byte (mb, CEE_PREFIX1);
467 mono_mb_emit_byte (mb, CEE_LDFTN);
468 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, method));
469 mono_mb_emit_byte (mb, CEE_CALLI);
470 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, opt_sig));
474 mono_mb_emit_native_call (MonoMethodBuilder *mb, MonoMethodSignature *sig, gpointer func)
476 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
477 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
478 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, func));
479 mono_mb_emit_byte (mb, CEE_CALLI);
480 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, sig));
484 mono_mb_emit_exception (MonoMethodBuilder *mb)
486 /* fixme: we need a better way to throw exception,
487 * supporting several exception types and messages */
488 static MonoMethod *missing_method_ctor = NULL;
490 if (!missing_method_ctor) {
491 MonoClass *mme = mono_class_from_name (mono_defaults.corlib, "System", "MissingMethodException");
493 mono_class_init (mme);
494 for (i = 0; i < mme->method.count; ++i) {
495 if (strcmp (mme->methods [i]->name, ".ctor") == 0 && mme->methods [i]->signature->param_count == 0) {
496 missing_method_ctor = mme->methods [i];
501 mono_mb_emit_byte (mb, CEE_NEWOBJ);
502 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, missing_method_ctor));
503 mono_mb_emit_byte (mb, CEE_THROW);
508 mono_mb_emit_add_to_local (MonoMethodBuilder *mb, guint8 local, gint8 incr)
510 mono_mb_emit_ldloc (mb, local);
511 mono_mb_emit_icon (mb, incr);
512 mono_mb_emit_byte (mb, CEE_ADD);
513 mono_mb_emit_stloc (mb, local);
517 emit_ptr_to_str_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv,
518 int usize, int msize)
521 case MONO_MARSHAL_CONV_BOOL_I4:
522 mono_mb_emit_byte (mb, CEE_LDLOC_0);
523 mono_mb_emit_byte (mb, CEE_LDIND_I);
524 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
525 mono_mb_emit_byte (mb, 5);
526 mono_mb_emit_byte (mb, CEE_LDLOC_1);
527 mono_mb_emit_byte (mb, CEE_LDC_I4_1);
528 mono_mb_emit_byte (mb, CEE_STIND_I1);
529 mono_mb_emit_byte (mb, CEE_BR_S);
530 mono_mb_emit_byte (mb, 3);
531 mono_mb_emit_byte (mb, CEE_LDLOC_1);
532 mono_mb_emit_byte (mb, CEE_LDC_I4_0);
533 mono_mb_emit_byte (mb, CEE_STIND_I1);
535 case MONO_MARSHAL_CONV_ARRAY_BYVALARRAY: {
539 if (type->type == MONO_TYPE_ARRAY)
540 eclass = mono_class_from_mono_type (type->data.array->type);
541 else if (type->type == MONO_TYPE_SZARRAY) {
542 eclass = mono_class_from_mono_type (type->data.type);
544 g_assert_not_reached ();
547 if (eclass->valuetype)
548 esize = mono_class_instance_size (eclass) - sizeof (MonoObject);
550 esize = sizeof (gpointer);
552 /* create a new array */
553 /* fixme: this only works for SZARRAYS */
554 mono_mb_emit_byte (mb, CEE_LDLOC_1);
555 mono_mb_emit_icon (mb, msize / esize);
556 mono_mb_emit_byte (mb, CEE_NEWARR);
557 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, eclass));
558 mono_mb_emit_byte (mb, CEE_STIND_I);
560 /* copy the elements */
561 mono_mb_emit_byte (mb, CEE_LDLOC_1);
562 mono_mb_emit_byte (mb, CEE_LDIND_I);
563 mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoArray, vector));
564 mono_mb_emit_byte (mb, CEE_ADD);
565 mono_mb_emit_byte (mb, CEE_LDLOC_0);
566 mono_mb_emit_icon (mb, usize);
567 mono_mb_emit_byte (mb, CEE_PREFIX1);
568 mono_mb_emit_byte (mb, CEE_CPBLK);
572 case MONO_MARSHAL_CONV_STR_BYVALSTR:
573 mono_mb_emit_byte (mb, CEE_LDLOC_1);
574 mono_mb_emit_byte (mb, CEE_LDLOC_0);
575 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
576 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
577 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
578 mono_mb_emit_byte (mb, CEE_STIND_I);
580 case MONO_MARSHAL_CONV_STR_LPTSTR:
581 case MONO_MARSHAL_CONV_STR_LPSTR:
582 mono_mb_emit_byte (mb, CEE_LDLOC_1);
583 mono_mb_emit_byte (mb, CEE_LDLOC_0);
584 mono_mb_emit_byte (mb, CEE_LDIND_I);
585 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
586 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
587 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
588 mono_mb_emit_byte (mb, CEE_STIND_I);
590 case MONO_MARSHAL_CONV_OBJECT_STRUCT: {
591 MonoClass *klass = mono_class_from_mono_type (type);
592 int src_var, dst_var;
594 src_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
595 dst_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
597 /* *dst = new object */
598 mono_mb_emit_byte (mb, CEE_LDLOC_1);
599 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
600 mono_mb_emit_byte (mb, CEE_MONO_NEWOBJ);
601 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, klass));
602 mono_mb_emit_byte (mb, CEE_STIND_I);
604 /* save the old src pointer */
605 mono_mb_emit_byte (mb, CEE_LDLOC_0);
606 mono_mb_emit_stloc (mb, src_var);
607 /* save the old dst pointer */
608 mono_mb_emit_byte (mb, CEE_LDLOC_1);
609 mono_mb_emit_stloc (mb, dst_var);
611 /* dst = pointer to newly created object data */
612 mono_mb_emit_byte (mb, CEE_LDLOC_1);
613 mono_mb_emit_byte (mb, CEE_LDIND_I);
614 mono_mb_emit_icon (mb, sizeof (MonoObject));
615 mono_mb_emit_byte (mb, CEE_ADD);
616 mono_mb_emit_byte (mb, CEE_STLOC_1);
618 emit_struct_conv (mb, klass, TRUE);
620 /* restore the old src pointer */
621 mono_mb_emit_ldloc (mb, src_var);
622 mono_mb_emit_byte (mb, CEE_STLOC_0);
623 /* restore the old dst pointer */
624 mono_mb_emit_ldloc (mb, dst_var);
625 mono_mb_emit_byte (mb, CEE_STLOC_1);
628 case MONO_MARSHAL_CONV_DEL_FTN: {
629 // fixme: we never convert functions back to delegates, dont
630 // know if thats the correct behaviour
633 case MONO_MARSHAL_CONV_STR_LPWSTR:
634 case MONO_MARSHAL_CONV_STR_BSTR:
635 case MONO_MARSHAL_CONV_STR_ANSIBSTR:
636 case MONO_MARSHAL_CONV_STR_TBSTR:
637 case MONO_MARSHAL_CONV_ARRAY_SAVEARRAY:
638 case MONO_MARSHAL_CONV_ARRAY_LPARRAY:
639 case MONO_MARSHAL_CONV_STR_BYVALWSTR:
640 case MONO_MARSHAL_CONV_BOOL_VARIANTBOOL:
642 g_warning ("marshaling conversion %d not implemented", conv);
643 g_assert_not_reached ();
648 emit_str_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv conv, int usize, int msize)
653 case MONO_MARSHAL_CONV_BOOL_I4:
654 mono_mb_emit_byte (mb, CEE_LDLOC_1);
655 mono_mb_emit_byte (mb, CEE_LDLOC_0);
656 mono_mb_emit_byte (mb, CEE_LDIND_U1);
657 mono_mb_emit_byte (mb, CEE_STIND_I4);
659 case MONO_MARSHAL_CONV_STR_LPWSTR:
660 case MONO_MARSHAL_CONV_STR_LPSTR:
661 case MONO_MARSHAL_CONV_STR_LPTSTR:
662 case MONO_MARSHAL_CONV_STR_BSTR:
663 case MONO_MARSHAL_CONV_STR_ANSIBSTR:
664 case MONO_MARSHAL_CONV_STR_TBSTR:
665 /* free space if free == true */
666 mono_mb_emit_byte (mb, CEE_LDLOC_2);
667 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
668 mono_mb_emit_byte (mb, 4);
669 mono_mb_emit_byte (mb, CEE_LDLOC_1);
670 mono_mb_emit_byte (mb, CEE_LDIND_I);
671 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
672 mono_mb_emit_byte (mb, CEE_MONO_FREE);
674 mono_mb_emit_byte (mb, CEE_LDLOC_1);
675 mono_mb_emit_byte (mb, CEE_LDLOC_0);
676 mono_mb_emit_byte (mb, CEE_LDIND_I);
677 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
678 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
679 mono_mb_emit_byte (mb, conv);
680 mono_mb_emit_byte (mb, CEE_STIND_I);
682 case MONO_MARSHAL_CONV_ARRAY_SAVEARRAY:
683 case MONO_MARSHAL_CONV_ARRAY_LPARRAY:
684 case MONO_MARSHAL_CONV_DEL_FTN:
685 mono_mb_emit_byte (mb, CEE_LDLOC_1);
686 mono_mb_emit_byte (mb, CEE_LDLOC_0);
687 mono_mb_emit_byte (mb, CEE_LDIND_I);
688 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
689 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
690 mono_mb_emit_byte (mb, conv);
691 mono_mb_emit_byte (mb, CEE_STIND_I);
693 case MONO_MARSHAL_CONV_STR_BYVALSTR:
694 case MONO_MARSHAL_CONV_STR_BYVALWSTR: {
698 mono_mb_emit_byte (mb, CEE_LDLOC_1); /* dst */
699 mono_mb_emit_byte (mb, CEE_LDLOC_0);
700 mono_mb_emit_byte (mb, CEE_LDIND_I); /* src String */
701 mono_mb_emit_icon (mb, usize);
702 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
703 mono_mb_emit_byte (mb, CEE_MONO_PROC3);
704 mono_mb_emit_byte (mb, conv);
707 case MONO_MARSHAL_CONV_ARRAY_BYVALARRAY: {
711 mono_mb_emit_byte (mb, CEE_LDLOC_0);
712 mono_mb_emit_byte (mb, CEE_LDIND_I);
713 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
715 mono_mb_emit_byte (mb, 0);
717 mono_mb_emit_byte (mb, CEE_LDLOC_1);
718 mono_mb_emit_byte (mb, CEE_LDLOC_0);
719 mono_mb_emit_byte (mb, CEE_LDIND_I);
720 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
721 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
722 mono_mb_emit_icon (mb, G_STRUCT_OFFSET (MonoArray, vector));
723 mono_mb_emit_byte (mb, CEE_ADD);
724 mono_mb_emit_icon (mb, usize);
725 mono_mb_emit_byte (mb, CEE_PREFIX1);
726 mono_mb_emit_byte (mb, CEE_CPBLK);
727 mono_mb_patch_addr_s (mb, pos, mb->pos - pos - 1);
730 case MONO_MARSHAL_CONV_OBJECT_STRUCT: {
731 int src_var, dst_var;
733 src_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
734 dst_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
736 mono_mb_emit_byte (mb, CEE_LDLOC_0);
737 mono_mb_emit_byte (mb, CEE_LDIND_I);
738 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
740 mono_mb_emit_byte (mb, 0);
742 /* save the old src pointer */
743 mono_mb_emit_byte (mb, CEE_LDLOC_0);
744 mono_mb_emit_stloc (mb, src_var);
745 /* save the old dst pointer */
746 mono_mb_emit_byte (mb, CEE_LDLOC_1);
747 mono_mb_emit_stloc (mb, dst_var);
749 /* src = pointer to object data */
750 mono_mb_emit_byte (mb, CEE_LDLOC_0);
751 mono_mb_emit_byte (mb, CEE_LDIND_I);
752 mono_mb_emit_icon (mb, sizeof (MonoObject));
753 mono_mb_emit_byte (mb, CEE_ADD);
754 mono_mb_emit_byte (mb, CEE_STLOC_0);
756 emit_struct_conv (mb, mono_class_from_mono_type (type), FALSE);
758 /* restore the old src pointer */
759 mono_mb_emit_ldloc (mb, src_var);
760 mono_mb_emit_byte (mb, CEE_STLOC_0);
761 /* restore the old dst pointer */
762 mono_mb_emit_ldloc (mb, dst_var);
763 mono_mb_emit_byte (mb, CEE_STLOC_1);
765 mono_mb_patch_addr_s (mb, pos, mb->pos - pos - 1);
768 case MONO_MARSHAL_CONV_BOOL_VARIANTBOOL:
770 g_warning ("marshalling conversion %d not implemented", conv);
771 g_assert_not_reached ();
776 emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
778 MonoMarshalType *info;
781 info = mono_marshal_load_type_info (klass);
783 if ((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) {
784 mono_mb_emit_byte (mb, CEE_LDLOC_1);
785 mono_mb_emit_byte (mb, CEE_LDLOC_0);
786 mono_mb_emit_icon (mb, mono_class_value_size (klass, NULL));
787 mono_mb_emit_byte (mb, CEE_PREFIX1);
788 mono_mb_emit_byte (mb, CEE_CPBLK);
792 for (i = 0; i < info->num_fields; i++) {
793 MonoMarshalNative ntype;
794 MonoMarshalConv conv;
795 MonoType *ftype = info->fields [i].field->type;
798 gboolean last_field = i < (info->num_fields -1) ? 0 : 1;
800 if (ftype->attrs & FIELD_ATTRIBUTE_STATIC)
803 ntype = mono_type_to_unmanaged (ftype, info->fields [i].mspec, TRUE, klass->unicode, &conv);
806 msize = klass->instance_size - info->fields [i].field->offset;
807 usize = info->native_size - info->fields [i].offset;
809 msize = klass->fields [i + 1].offset - info->fields [i].field->offset;
810 usize = info->fields [i + 1].offset - info->fields [i].offset;
812 g_assert (msize > 0 && usize > 0);
815 case MONO_MARSHAL_CONV_NONE: {
818 if (ftype->byref || ftype->type == MONO_TYPE_I ||
819 ftype->type == MONO_TYPE_U) {
820 mono_mb_emit_byte (mb, CEE_LDLOC_1);
821 mono_mb_emit_byte (mb, CEE_LDLOC_0);
822 mono_mb_emit_byte (mb, CEE_LDIND_I);
823 mono_mb_emit_byte (mb, CEE_STIND_I);
832 #if SIZEOF_VOID_P == 4
835 mono_mb_emit_byte (mb, CEE_LDLOC_1);
836 mono_mb_emit_byte (mb, CEE_LDLOC_0);
837 mono_mb_emit_byte (mb, CEE_LDIND_I4);
838 mono_mb_emit_byte (mb, CEE_STIND_I4);
842 case MONO_TYPE_BOOLEAN:
843 mono_mb_emit_byte (mb, CEE_LDLOC_1);
844 mono_mb_emit_byte (mb, CEE_LDLOC_0);
845 mono_mb_emit_byte (mb, CEE_LDIND_I1);
846 mono_mb_emit_byte (mb, CEE_STIND_I1);
850 mono_mb_emit_byte (mb, CEE_LDLOC_1);
851 mono_mb_emit_byte (mb, CEE_LDLOC_0);
852 mono_mb_emit_byte (mb, CEE_LDIND_I2);
853 mono_mb_emit_byte (mb, CEE_STIND_I2);
857 #if SIZEOF_VOID_P == 8
860 mono_mb_emit_byte (mb, CEE_LDLOC_1);
861 mono_mb_emit_byte (mb, CEE_LDLOC_0);
862 mono_mb_emit_byte (mb, CEE_LDIND_I8);
863 mono_mb_emit_byte (mb, CEE_STIND_I8);
866 mono_mb_emit_byte (mb, CEE_LDLOC_1);
867 mono_mb_emit_byte (mb, CEE_LDLOC_0);
868 mono_mb_emit_byte (mb, CEE_LDIND_R4);
869 mono_mb_emit_byte (mb, CEE_STIND_R4);
872 mono_mb_emit_byte (mb, CEE_LDLOC_1);
873 mono_mb_emit_byte (mb, CEE_LDLOC_0);
874 mono_mb_emit_byte (mb, CEE_LDIND_R8);
875 mono_mb_emit_byte (mb, CEE_STIND_R8);
877 case MONO_TYPE_VALUETYPE:
878 if (ftype->data.klass->enumtype) {
879 t = ftype->data.klass->enum_basetype->type;
882 emit_struct_conv (mb, ftype->data.klass, to_object);
885 g_warning ("marshaling type %02x not implemented", ftype->type);
886 g_assert_not_reached ();
892 emit_ptr_to_str_conv (mb, ftype, conv, usize, msize);
894 emit_str_to_ptr_conv (mb, ftype, conv, usize, msize);
898 mono_mb_emit_add_to_local (mb, 0, usize);
899 mono_mb_emit_add_to_local (mb, 1, msize);
901 mono_mb_emit_add_to_local (mb, 0, msize);
902 mono_mb_emit_add_to_local (mb, 1, usize);
907 static MonoAsyncResult *
908 mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
910 MonoMethodMessage *msg;
911 MonoDelegate *async_callback;
915 MonoMethod *method = NULL;
920 klass = delegate->object.vtable->klass;
922 method = mono_get_delegate_invoke (klass);
923 for (i = 0; i < klass->method.count; ++i) {
924 if (klass->methods [i]->name[0] == 'B' &&
925 !strcmp ("BeginInvoke", klass->methods [i]->name)) {
926 method = klass->methods [i];
931 g_assert (method != NULL);
933 im = mono_get_delegate_invoke (method->klass);
935 msg = mono_method_call_message_new (method, params, im, &async_callback, &state);
937 return mono_thread_pool_add ((MonoObject *)delegate, msg, async_callback, state);
941 mono_mb_emit_save_args (MonoMethodBuilder *mb, MonoMethodSignature *sig, gboolean save_this)
943 int i, params_var, tmp_var;
945 /* allocate local (pointer) *params[] */
946 params_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
947 /* allocate local (pointer) tmp */
948 tmp_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
950 /* alloate space on stack to store an array of pointers to the arguments */
951 mono_mb_emit_icon (mb, sizeof (gpointer) * (sig->param_count + 1));
952 mono_mb_emit_byte (mb, CEE_PREFIX1);
953 mono_mb_emit_byte (mb, CEE_LOCALLOC);
954 mono_mb_emit_stloc (mb, params_var);
957 mono_mb_emit_ldloc (mb, params_var);
958 mono_mb_emit_stloc (mb, tmp_var);
960 if (save_this && sig->hasthis) {
961 mono_mb_emit_ldloc (mb, tmp_var);
962 mono_mb_emit_ldarg_addr (mb, 0);
963 mono_mb_emit_byte (mb, CEE_STIND_I);
964 /* tmp = tmp + sizeof (gpointer) */
965 if (sig->param_count)
966 mono_mb_emit_add_to_local (mb, tmp_var, sizeof (gpointer));
970 for (i = 0; i < sig->param_count; i++) {
971 mono_mb_emit_ldloc (mb, tmp_var);
972 mono_mb_emit_ldarg_addr (mb, i + sig->hasthis);
973 mono_mb_emit_byte (mb, CEE_STIND_I);
974 /* tmp = tmp + sizeof (gpointer) */
975 if (i < (sig->param_count - 1))
976 mono_mb_emit_add_to_local (mb, tmp_var, sizeof (gpointer));
983 mono_signature_to_name (MonoMethodSignature *sig, const char *prefix)
987 GString *res = g_string_new ("");
990 g_string_append (res, prefix);
991 g_string_append_c (res, '_');
994 mono_type_get_desc (res, sig->ret, FALSE);
996 for (i = 0; i < sig->param_count; ++i) {
997 g_string_append_c (res, '_');
998 mono_type_get_desc (res, sig->params [i], FALSE);
1001 g_string_free (res, FALSE);
1006 mono_marshal_get_delegate_begin_invoke (MonoMethod *method)
1008 MonoMethodSignature *sig;
1009 static MonoMethodSignature *csig = NULL;
1010 MonoMethodBuilder *mb;
1016 g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class &&
1017 !strcmp (method->name, "BeginInvoke"));
1019 sig = method->signature;
1021 cache = method->klass->image->delegate_begin_invoke_cache;
1022 if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
1025 g_assert (sig->hasthis);
1028 int sigsize = sizeof (MonoMethodSignature) + 2 * sizeof (MonoType *);
1029 csig = g_malloc0 (sigsize);
1031 /* MonoAsyncResult * begin_invoke (MonoDelegate *delegate, gpointer params[]) */
1032 csig->param_count = 2;
1033 csig->ret = &mono_defaults.object_class->byval_arg;
1034 csig->params [0] = &mono_defaults.object_class->byval_arg;
1035 csig->params [1] = &mono_defaults.int_class->byval_arg;
1038 name = mono_signature_to_name (sig, "begin_invoke");
1039 mb = mono_mb_new (mono_defaults.multicastdelegate_class, name, MONO_WRAPPER_DELEGATE_BEGIN_INVOKE);
1042 mb->method->save_lmf = 1;
1044 params_var = mono_mb_emit_save_args (mb, sig, FALSE);
1046 mono_mb_emit_ldarg (mb, 0);
1047 mono_mb_emit_ldloc (mb, params_var);
1048 mono_mb_emit_native_call (mb, csig, mono_delegate_begin_invoke);
1049 mono_mb_emit_byte (mb, CEE_RET);
1051 res = mono_mb_create_method (mb, sig, sig->param_count + 16);
1053 g_hash_table_insert (cache, sig, res);
1058 mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
1060 MonoDomain *domain = mono_domain_get ();
1061 MonoAsyncResult *ares;
1062 MonoMethod *method = NULL;
1063 MonoMethodSignature *sig;
1064 MonoMethodMessage *msg;
1065 MonoObject *res, *exc;
1066 MonoArray *out_args;
1070 g_assert (delegate);
1072 if (!delegate->method_info || !delegate->method_info->method)
1073 g_assert_not_reached ();
1075 klass = delegate->object.vtable->klass;
1077 for (i = 0; i < klass->method.count; ++i) {
1078 if (klass->methods [i]->name[0] == 'E' &&
1079 !strcmp ("EndInvoke", klass->methods [i]->name)) {
1080 method = klass->methods [i];
1085 g_assert (method != NULL);
1087 sig = method->signature;
1089 msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
1091 ares = mono_array_get (msg->args, gpointer, sig->param_count - 1);
1094 res = mono_thread_pool_finish (ares, &out_args, &exc);
1097 char *strace = mono_string_to_utf8 (((MonoException*)exc)->stack_trace);
1099 tmp = g_strdup_printf ("%s\nException Rethrown at:\n", strace);
1101 ((MonoException*)exc)->stack_trace = mono_string_new (domain, tmp);
1103 mono_raise_exception ((MonoException*)exc);
1106 mono_method_return_message_restore (method, params, out_args);
1111 mono_mb_emit_restore_result (MonoMethodBuilder *mb, MonoType *return_type)
1113 if (return_type->byref)
1114 return_type = &mono_defaults.int_class->byval_arg;
1115 else if (return_type->type == MONO_TYPE_VALUETYPE && return_type->data.klass->enumtype)
1116 return_type = return_type->data.klass->enum_basetype;
1118 switch (return_type->type) {
1119 case MONO_TYPE_VOID:
1120 g_assert_not_reached ();
1122 case MONO_TYPE_STRING:
1123 case MONO_TYPE_CLASS:
1124 case MONO_TYPE_OBJECT:
1125 case MONO_TYPE_ARRAY:
1126 case MONO_TYPE_SZARRAY:
1130 case MONO_TYPE_BOOLEAN:
1131 mono_mb_emit_byte (mb, CEE_UNBOX);
1132 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1133 mono_mb_emit_byte (mb, CEE_LDIND_U1);
1136 mono_mb_emit_byte (mb, CEE_UNBOX);
1137 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1138 mono_mb_emit_byte (mb, CEE_LDIND_I1);
1141 case MONO_TYPE_CHAR:
1142 mono_mb_emit_byte (mb, CEE_UNBOX);
1143 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1144 mono_mb_emit_byte (mb, CEE_LDIND_U2);
1147 mono_mb_emit_byte (mb, CEE_UNBOX);
1148 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1149 mono_mb_emit_byte (mb, CEE_LDIND_I2);
1153 mono_mb_emit_byte (mb, CEE_UNBOX);
1154 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1155 mono_mb_emit_byte (mb, CEE_LDIND_I);
1158 mono_mb_emit_byte (mb, CEE_UNBOX);
1159 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1160 mono_mb_emit_byte (mb, CEE_LDIND_I4);
1163 mono_mb_emit_byte (mb, CEE_UNBOX);
1164 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1165 mono_mb_emit_byte (mb, CEE_LDIND_U4);
1169 mono_mb_emit_byte (mb, CEE_UNBOX);
1170 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1171 mono_mb_emit_byte (mb, CEE_LDIND_I8);
1174 mono_mb_emit_byte (mb, CEE_UNBOX);
1175 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1176 mono_mb_emit_byte (mb, CEE_LDIND_R4);
1179 mono_mb_emit_byte (mb, CEE_UNBOX);
1180 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (return_type)));
1181 mono_mb_emit_byte (mb, CEE_LDIND_R8);
1183 case MONO_TYPE_VALUETYPE: {
1185 mono_mb_emit_byte (mb, CEE_UNBOX);
1186 class = mono_mb_add_data (mb, mono_class_from_mono_type (return_type));
1187 mono_mb_emit_i4 (mb, class);
1188 mono_mb_emit_byte (mb, CEE_LDOBJ);
1189 mono_mb_emit_i4 (mb, class);
1193 g_warning ("type 0x%x not handled", return_type->type);
1194 g_assert_not_reached ();
1197 mono_mb_emit_byte (mb, CEE_RET);
1201 mono_marshal_get_delegate_end_invoke (MonoMethod *method)
1203 MonoMethodSignature *sig;
1204 static MonoMethodSignature *csig = NULL;
1205 MonoMethodBuilder *mb;
1211 g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class &&
1212 !strcmp (method->name, "EndInvoke"));
1214 sig = method->signature;
1216 cache = method->klass->image->delegate_end_invoke_cache;
1217 if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
1220 g_assert (sig->hasthis);
1223 int sigsize = sizeof (MonoMethodSignature) + 2 * sizeof (MonoType *);
1224 csig = g_malloc0 (sigsize);
1226 /* MonoObject *end_invoke (MonoDelegate *delegate, gpointer params[]) */
1227 csig->param_count = 2;
1228 csig->ret = &mono_defaults.object_class->byval_arg;
1229 csig->params [0] = &mono_defaults.object_class->byval_arg;
1230 csig->params [1] = &mono_defaults.int_class->byval_arg;
1233 name = mono_signature_to_name (sig, "end_invoke");
1234 mb = mono_mb_new (mono_defaults.multicastdelegate_class, name, MONO_WRAPPER_DELEGATE_END_INVOKE);
1237 mb->method->save_lmf = 1;
1239 params_var = mono_mb_emit_save_args (mb, sig, FALSE);
1241 mono_mb_emit_ldarg (mb, 0);
1242 mono_mb_emit_ldloc (mb, params_var);
1243 mono_mb_emit_native_call (mb, csig, mono_delegate_end_invoke);
1245 if (sig->ret->type == MONO_TYPE_VOID) {
1246 mono_mb_emit_byte (mb, CEE_POP);
1247 mono_mb_emit_byte (mb, CEE_RET);
1249 mono_mb_emit_restore_result (mb, sig->ret);
1251 res = mono_mb_create_method (mb, sig, sig->param_count + 16);
1253 g_hash_table_insert (cache, sig, res);
1259 mono_remoting_wrapper (MonoMethod *method, gpointer *params)
1261 MonoMethodMessage *msg;
1262 MonoTransparentProxy *this;
1263 MonoObject *res, *exc;
1264 MonoArray *out_args;
1266 this = *((MonoTransparentProxy **)params [0]);
1269 g_assert (((MonoObject *)this)->vtable->klass == mono_defaults.transparent_proxy_class);
1271 /* skip the this pointer */
1274 msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
1276 res = mono_remoting_invoke ((MonoObject *)this->rp, msg, &exc, &out_args);
1279 mono_raise_exception ((MonoException *)exc);
1281 mono_method_return_message_restore (method, params, out_args);
1287 mono_marshal_get_remoting_invoke (MonoMethod *method)
1289 MonoMethodSignature *sig;
1290 static MonoMethodSignature *csig = NULL;
1291 MonoMethodBuilder *mb;
1298 if (method->wrapper_type == MONO_WRAPPER_REMOTING_INVOKE)
1301 sig = method->signature;
1303 /* we cant remote methods without this pointer */
1307 cache = method->klass->image->remoting_invoke_cache;
1308 if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
1312 int sigsize = sizeof (MonoMethodSignature) + 2 * sizeof (MonoType *);
1313 csig = g_malloc0 (sigsize);
1315 /* MonoObject *remoting_wrapper (MonoMethod *method, gpointer params[]) */
1316 csig->param_count = 2;
1317 csig->ret = &mono_defaults.object_class->byval_arg;
1318 csig->params [0] = &mono_defaults.int_class->byval_arg;
1319 csig->params [1] = &mono_defaults.int_class->byval_arg;
1322 mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_REMOTING_INVOKE);
1323 mb->method->save_lmf = 1;
1325 params_var = mono_mb_emit_save_args (mb, sig, TRUE);
1327 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1328 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
1329 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, method));
1330 mono_mb_emit_ldloc (mb, params_var);
1331 mono_mb_emit_native_call (mb, csig, mono_remoting_wrapper);
1333 if (sig->ret->type == MONO_TYPE_VOID)
1334 mono_mb_emit_byte (mb, CEE_POP);
1336 mono_mb_emit_restore_result (mb, sig->ret);
1338 res = mono_mb_create_method (mb, sig, sig->param_count + 16);
1340 g_hash_table_insert (cache, method, res);
1345 * the returned method invokes all methods in a multicast delegate
1348 mono_marshal_get_delegate_invoke (MonoMethod *method)
1350 MonoMethodSignature *sig, *static_sig;
1352 MonoMethodBuilder *mb;
1358 g_assert (method && method->klass->parent == mono_defaults.multicastdelegate_class &&
1359 !strcmp (method->name, "Invoke"));
1361 sig = method->signature;
1363 cache = method->klass->image->delegate_invoke_cache;
1364 if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
1367 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1368 static_sig = g_memdup (sig, sigsize);
1369 static_sig->hasthis = 0;
1371 name = mono_signature_to_name (sig, "invoke");
1372 mb = mono_mb_new (mono_defaults.multicastdelegate_class, name, MONO_WRAPPER_DELEGATE_INVOKE);
1375 /* allocate local 0 (object) */
1376 mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1378 g_assert (sig->hasthis);
1382 * prev.Invoke( args .. );
1383 * return this.<target>( args .. );
1386 /* get this->prev */
1387 mono_mb_emit_ldarg (mb, 0);
1388 mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoMulticastDelegate, prev));
1389 mono_mb_emit_byte (mb, CEE_LDIND_I );
1390 mono_mb_emit_stloc (mb, 0);
1392 /* if prev != null */
1393 mono_mb_emit_ldloc (mb, 0);
1394 mono_mb_emit_byte (mb, CEE_BRFALSE);
1397 mono_mb_emit_i4 (mb, 0);
1400 mono_mb_emit_ldloc (mb, 0);
1401 for (i = 0; i < sig->param_count; i++)
1402 mono_mb_emit_ldarg (mb, i + 1);
1403 mono_mb_emit_managed_call (mb, method, method->signature);
1404 if (sig->ret->type != MONO_TYPE_VOID)
1405 mono_mb_emit_byte (mb, CEE_POP);
1407 /* continued or prev == null */
1408 mono_mb_patch_addr (mb, pos0, mb->pos - (pos0 + 4));
1410 /* get this->target */
1411 mono_mb_emit_ldarg (mb, 0);
1412 mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoDelegate, target));
1413 mono_mb_emit_byte (mb, CEE_LDIND_I );
1414 mono_mb_emit_stloc (mb, 0);
1416 /* if target != null */
1417 mono_mb_emit_ldloc (mb, 0);
1418 mono_mb_emit_byte (mb, CEE_BRFALSE);
1420 mono_mb_emit_i4 (mb, 0);
1422 /* then call this->method_ptr nonstatic */
1423 mono_mb_emit_ldloc (mb, 0);
1424 for (i = 0; i < sig->param_count; ++i)
1425 mono_mb_emit_ldarg (mb, i + 1);
1426 mono_mb_emit_ldarg (mb, 0);
1427 mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
1428 mono_mb_emit_byte (mb, CEE_LDIND_I );
1429 mono_mb_emit_byte (mb, CEE_CALLI);
1430 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, sig));
1432 mono_mb_emit_byte (mb, CEE_BR);
1434 mono_mb_emit_i4 (mb, 0);
1436 /* else [target == null] call this->method_ptr static */
1437 mono_mb_patch_addr (mb, pos0, mb->pos - (pos0 + 4));
1439 for (i = 0; i < sig->param_count; ++i)
1440 mono_mb_emit_ldarg (mb, i + 1);
1441 mono_mb_emit_ldarg (mb, 0);
1442 mono_mb_emit_ldflda (mb, G_STRUCT_OFFSET (MonoDelegate, method_ptr));
1443 mono_mb_emit_byte (mb, CEE_LDIND_I );
1444 mono_mb_emit_byte (mb, CEE_CALLI);
1445 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, static_sig));
1448 mono_mb_patch_addr (mb, pos1, mb->pos - (pos1 + 4));
1449 mono_mb_emit_byte (mb, CEE_RET);
1451 res = mono_mb_create_method (mb, sig, sig->param_count + 16);
1454 g_hash_table_insert (cache, sig, res);
1460 * generates IL code for the runtime invoke function
1461 * MonoObject *runtime_invoke (MonoObject *this, void **params, MonoObject **exc)
1463 * we also catch exceptions if exc != null
1466 mono_marshal_get_runtime_invoke (MonoMethod *method)
1468 MonoMethodSignature *sig, *csig;
1469 MonoExceptionClause *clause;
1470 MonoMethodHeader *header;
1471 MonoMethodBuilder *mb;
1474 static MonoString *string_dummy = NULL;
1475 int i, pos, sigsize;
1479 cache = method->klass->image->runtime_invoke_cache;
1480 if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
1483 /* to make it work with our special string constructors */
1485 string_dummy = mono_string_new_wrapper ("dummy");
1487 sig = method->signature;
1489 sigsize = sizeof (MonoMethodSignature) + 3 * sizeof (MonoType *);
1490 csig = g_malloc0 (sigsize);
1492 csig->param_count = 3;
1493 csig->ret = &mono_defaults.object_class->byval_arg;
1494 csig->params [0] = &mono_defaults.object_class->byval_arg;
1495 csig->params [1] = &mono_defaults.int_class->byval_arg;
1496 csig->params [2] = &mono_defaults.int_class->byval_arg;
1498 mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_RUNTIME_INVOKE);
1500 /* allocate local 0 (object) tmp */
1501 mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1502 /* allocate local 1 (object) exc */
1503 mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1505 /* cond set *exc to null */
1506 mono_mb_emit_byte (mb, CEE_LDARG_2);
1507 mono_mb_emit_byte (mb, CEE_BRFALSE_S);
1508 mono_mb_emit_byte (mb, 3);
1509 mono_mb_emit_byte (mb, CEE_LDARG_2);
1510 mono_mb_emit_byte (mb, CEE_LDNULL);
1511 mono_mb_emit_byte (mb, CEE_STIND_I);
1514 if (method->string_ctor) {
1515 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1516 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
1517 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, string_dummy));
1519 mono_mb_emit_ldarg (mb, 0);
1520 if (method->klass->valuetype) {
1521 mono_mb_emit_byte (mb, CEE_UNBOX);
1522 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, method->klass));
1527 for (i = 0; i < sig->param_count; i++) {
1528 MonoType *t = sig->params [i];
1531 mono_mb_emit_ldarg (mb, 1);
1533 mono_mb_emit_icon (mb, sizeof (gpointer) * i);
1534 mono_mb_emit_byte (mb, CEE_ADD);
1536 mono_mb_emit_byte (mb, CEE_LDIND_I);
1541 type = sig->params [i]->type;
1545 mono_mb_emit_byte (mb, CEE_LDIND_I1);
1547 case MONO_TYPE_BOOLEAN:
1549 mono_mb_emit_byte (mb, CEE_LDIND_U1);
1552 mono_mb_emit_byte (mb, CEE_LDIND_I2);
1555 case MONO_TYPE_CHAR:
1556 mono_mb_emit_byte (mb, CEE_LDIND_U2);
1560 mono_mb_emit_byte (mb, CEE_LDIND_I);
1563 mono_mb_emit_byte (mb, CEE_LDIND_I4);
1566 mono_mb_emit_byte (mb, CEE_LDIND_U4);
1569 mono_mb_emit_byte (mb, CEE_LDIND_R4);
1572 mono_mb_emit_byte (mb, CEE_LDIND_R8);
1576 mono_mb_emit_byte (mb, CEE_LDIND_I8);
1578 case MONO_TYPE_STRING:
1579 case MONO_TYPE_CLASS:
1580 case MONO_TYPE_ARRAY:
1582 case MONO_TYPE_SZARRAY:
1583 case MONO_TYPE_OBJECT:
1586 case MONO_TYPE_VALUETYPE:
1587 if (t->data.klass->enumtype) {
1588 type = t->data.klass->enum_basetype->type;
1591 mono_mb_emit_byte (mb, CEE_LDOBJ);
1592 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, t->data.klass));
1595 g_assert_not_reached ();
1599 if (method->string_ctor) {
1600 MonoMethodSignature *strsig;
1602 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1603 strsig = g_memdup (sig, sigsize);
1604 strsig->ret = &mono_defaults.string_class->byval_arg;
1606 mono_mb_emit_managed_call (mb, method, strsig);
1608 mono_mb_emit_managed_call (mb, method, NULL);
1610 if (sig->ret->byref) {
1612 g_assert_not_reached ();
1616 switch (sig->ret->type) {
1617 case MONO_TYPE_VOID:
1618 if (!method->string_ctor)
1619 mono_mb_emit_byte (mb, CEE_LDNULL);
1621 case MONO_TYPE_BOOLEAN:
1622 case MONO_TYPE_CHAR:
1635 case MONO_TYPE_VALUETYPE:
1636 /* box value types */
1637 mono_mb_emit_byte (mb, CEE_BOX);
1638 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, mono_class_from_mono_type (sig->ret)));
1640 case MONO_TYPE_STRING:
1641 case MONO_TYPE_CLASS:
1642 case MONO_TYPE_ARRAY:
1643 case MONO_TYPE_SZARRAY:
1644 case MONO_TYPE_OBJECT:
1649 g_assert_not_reached ();
1652 mono_mb_emit_stloc (mb, 0);
1654 mono_mb_emit_byte (mb, CEE_LEAVE);
1656 mono_mb_emit_i4 (mb, 0);
1658 clause = g_new0 (MonoExceptionClause, 1);
1659 clause->flags = MONO_EXCEPTION_CLAUSE_FILTER;
1660 clause->try_len = mb->pos;
1663 clause->token_or_filter = mb->pos;
1665 mono_mb_emit_byte (mb, CEE_POP);
1666 mono_mb_emit_byte (mb, CEE_LDARG_2);
1667 mono_mb_emit_byte (mb, CEE_LDC_I4_0);
1668 mono_mb_emit_byte (mb, CEE_PREFIX1);
1669 mono_mb_emit_byte (mb, CEE_CGT_UN);
1670 mono_mb_emit_byte (mb, CEE_PREFIX1);
1671 mono_mb_emit_byte (mb, CEE_ENDFILTER);
1673 clause->handler_offset = mb->pos;
1676 /* store exception */
1677 mono_mb_emit_stloc (mb, 1);
1679 mono_mb_emit_byte (mb, CEE_LDARG_2);
1680 mono_mb_emit_ldloc (mb, 1);
1681 mono_mb_emit_byte (mb, CEE_STIND_I);
1683 mono_mb_emit_byte (mb, CEE_LEAVE);
1684 mono_mb_emit_i4 (mb, 0);
1686 clause->handler_len = mb->pos - clause->handler_offset;
1689 mono_mb_patch_addr (mb, pos, mb->pos - (pos + 4));
1690 mono_mb_emit_ldloc (mb, 0);
1691 mono_mb_emit_byte (mb, CEE_RET);
1693 res = mono_mb_create_method (mb, csig, sig->param_count + 16);
1696 header = ((MonoMethodNormal *)res)->header;
1697 header->num_clauses = 1;
1698 header->clauses = clause;
1700 g_hash_table_insert (cache, method, res);
1706 * generates IL code to call managed methods from unmanaged code
1709 mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this)
1711 MonoMethodSignature *sig, *csig;
1712 MonoMethodBuilder *mb;
1716 int i, pos, sigsize, *tmp_locals;
1718 g_assert (method != NULL);
1720 cache = method->klass->image->managed_wrapper_cache;
1721 if (!this && (res = (MonoMethod *)g_hash_table_lookup (cache, method)))
1725 /* fime: howto free that memory ? */
1728 sig = method->signature;
1730 mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_NATIVE_TO_MANAGED);
1732 /* allocate local 0 (pointer) src_ptr */
1733 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1734 /* allocate local 1 (pointer) dst_ptr */
1735 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1736 /* allocate local 2 (boolean) delete_old */
1737 mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
1739 mono_mb_emit_byte (mb, CEE_LDNULL);
1740 mono_mb_emit_byte (mb, CEE_STLOC_2);
1742 /* we copy the signature, so that we can modify it */
1743 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1744 csig = g_memdup (sig, sigsize);
1748 /* fixme: howto handle this ? */
1752 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1753 mono_mb_emit_byte (mb, CEE_MONO_LDPTR);
1754 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, this));
1759 g_assert_not_reached ();
1764 /* we first do all conversions */
1765 tmp_locals = alloca (sizeof (int) * sig->param_count);
1766 for (i = 0; i < sig->param_count; i ++) {
1767 MonoType *t = sig->params [i];
1772 case MONO_TYPE_VALUETYPE:
1774 klass = sig->params [i]->data.klass;
1775 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
1776 klass->blittable || klass->enumtype)
1779 tmp_locals [i] = mono_mb_add_local (mb, &klass->byval_arg);
1782 mono_mb_emit_ldarg (mb, i);
1784 mono_mb_emit_ldarg_addr (mb, i);
1785 mono_mb_emit_byte (mb, CEE_STLOC_0);
1788 mono_mb_emit_byte (mb, CEE_LDLOC_0);
1789 mono_mb_emit_byte (mb, CEE_BRFALSE);
1791 mono_mb_emit_i4 (mb, 0);
1794 mono_mb_emit_ldloc_addr (mb, tmp_locals [i]);
1795 mono_mb_emit_byte (mb, CEE_STLOC_1);
1797 /* emit valuetype convnversion code code */
1798 emit_struct_conv (mb, klass, TRUE);
1801 mono_mb_patch_addr (mb, pos, mb->pos - (pos + 4));
1803 case MONO_TYPE_STRING:
1807 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1808 csig->params [i] = &mono_defaults.int_class->byval_arg;
1810 mono_mb_emit_ldarg (mb, i);
1811 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1812 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
1813 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
1814 mono_mb_emit_stloc (mb, tmp_locals [i]);
1816 case MONO_TYPE_ARRAY:
1817 case MONO_TYPE_SZARRAY:
1821 klass = mono_class_from_mono_type (t);
1823 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
1824 csig->params [i] = &mono_defaults.int_class->byval_arg;
1826 g_warning ("array marshaling not implemented");
1827 g_assert_not_reached ();
1832 for (i = 0; i < sig->param_count; i++) {
1833 MonoType *t = sig->params [i];
1836 case MONO_TYPE_BOOLEAN:
1850 mono_mb_emit_ldarg (mb, i);
1852 case MONO_TYPE_STRING:
1854 mono_mb_emit_ldarg (mb, i);
1856 g_assert (tmp_locals [i]);
1857 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1860 case MONO_TYPE_CLASS:
1861 case MONO_TYPE_ARRAY:
1862 case MONO_TYPE_SZARRAY:
1863 case MONO_TYPE_OBJECT:
1864 /* fixme: conversions ? */
1865 mono_mb_emit_ldarg (mb, i);
1867 case MONO_TYPE_VALUETYPE:
1868 klass = sig->params [i]->data.klass;
1869 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
1870 klass->blittable || klass->enumtype) {
1871 mono_mb_emit_ldarg (mb, i);
1875 g_assert (tmp_locals [i]);
1877 mono_mb_emit_ldloc_addr (mb, tmp_locals [i]);
1879 mono_mb_emit_ldloc (mb, tmp_locals [i]);
1882 g_warning ("type 0x%02x unknown", t->type);
1883 g_assert_not_reached ();
1887 mono_mb_emit_managed_call (mb, method, NULL);
1889 if (!sig->ret->byref) {
1890 switch (sig->ret->type) {
1891 case MONO_TYPE_VOID:
1892 case MONO_TYPE_BOOLEAN:
1908 case MONO_TYPE_STRING:
1909 csig->ret = &mono_defaults.int_class->byval_arg;
1911 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1912 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
1913 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPSTR);
1915 case MONO_TYPE_VALUETYPE: {
1917 klass = sig->ret->data.klass;
1918 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
1919 klass->blittable || klass->enumtype)
1922 /* load pointer to returned value type */
1923 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1924 mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
1926 /* store the address of the source into local variable 0 */
1927 mono_mb_emit_byte (mb, CEE_STLOC_0);
1928 /* allocate space for the native struct and
1929 * store the address into dst_ptr */
1930 tmp = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
1932 mono_mb_emit_icon (mb, mono_class_native_size (klass, NULL));
1933 mono_mb_emit_byte (mb, CEE_PREFIX1);
1934 mono_mb_emit_byte (mb, CEE_LOCALLOC);
1935 mono_mb_emit_byte (mb, CEE_STLOC_1);
1936 mono_mb_emit_byte (mb, CEE_LDLOC_1);
1937 mono_mb_emit_stloc (mb, tmp);
1939 /* emit valuetype conversion code */
1940 emit_struct_conv (mb, klass, FALSE);
1941 mono_mb_emit_ldloc (mb, tmp);
1942 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
1943 mono_mb_emit_byte (mb, CEE_MONO_RETOBJ);
1944 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, klass));
1948 g_warning ("return type 0x%02x unknown", sig->ret->type);
1949 g_assert_not_reached ();
1953 mono_mb_emit_byte (mb, CEE_RET);
1955 res = mono_mb_create_method (mb, csig, sig->param_count + 16);
1959 g_hash_table_insert (cache, method, res);
1965 * generates IL code for the icall wrapper (the generated method
1966 * calls the unamnaged code in func)
1969 mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gpointer func)
1971 MonoMethodSignature *csig;
1972 MonoMethodBuilder *mb;
1976 mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
1978 mb->method->save_lmf = 1;
1980 /* we copy the signature, so that we can modify it */
1981 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
1984 mono_mb_emit_byte (mb, CEE_LDARG_0);
1986 for (i = 0; i < sig->param_count; i++)
1987 mono_mb_emit_ldarg (mb, i + sig->hasthis);
1989 csig = g_memdup (sig, sigsize);
1992 mono_mb_emit_native_call (mb, csig, func);
1994 mono_mb_emit_byte (mb, CEE_RET);
1996 res = mono_mb_create_method (mb, csig, csig->param_count + 16);
2003 * generates IL code for the pinvoke wrapper (the generated method
2004 * calls the unamnage code in method->addr)
2007 mono_marshal_get_native_wrapper (MonoMethod *method)
2009 MonoMethodSignature *sig, *csig;
2010 MonoMethodBuilder *mb;
2011 MonoMarshalSpec **mspecs;
2015 gboolean pinvoke = FALSE;
2016 int i, pos, argnum, *tmp_locals;
2019 g_assert (method != NULL);
2021 cache = method->klass->image->native_wrapper_cache;
2022 if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
2025 sig = method->signature;
2027 if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) &&
2028 (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
2031 mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_MANAGED_TO_NATIVE);
2033 mb->method->save_lmf = 1;
2035 if (pinvoke && !method->addr)
2036 mono_lookup_pinvoke_call (method);
2038 if (!method->addr) {
2039 mono_mb_emit_exception (mb);
2040 res = mono_mb_create_method (mb, sig, sig->param_count + 16);
2042 g_hash_table_insert (cache, method, res);
2046 /* we copy the signature, so that we can modify it */
2047 sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
2049 /* internal calls: we simply push all arguments and call the method (no conversions) */
2050 if (method->iflags & (METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL | METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
2052 MonoMethodSignature *call_sig;
2054 /* hack - string constructors returns a value */
2055 if (method->string_ctor) {
2056 csig = g_memdup (sig, sigsize);
2057 csig->ret = &mono_defaults.string_class->byval_arg;
2062 mono_mb_emit_byte (mb, CEE_LDARG_0);
2064 for (i = 0; i < sig->param_count; i++)
2065 mono_mb_emit_ldarg (mb, i + sig->hasthis);
2067 call_sig = g_memdup (csig, sigsize);
2068 call_sig->pinvoke = 1;
2070 g_assert (method->addr);
2071 mono_mb_emit_native_call (mb, call_sig, method->addr);
2073 mono_mb_emit_byte (mb, CEE_RET);
2075 res = mono_mb_create_method (mb, csig, sig->param_count + 16);
2077 g_hash_table_insert (cache, method, res);
2083 mspecs = g_new (MonoMarshalSpec, sig->param_count + 1);
2084 mono_method_get_marshal_info (method, mspecs);
2086 /* pinvoke: we need to convert the arguments if necessary */
2088 csig = g_memdup (sig, sigsize);
2091 /* we allocate local for use with emit_struct_conv() */
2092 /* allocate local 0 (pointer) src_ptr */
2093 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2094 /* allocate local 1 (pointer) dst_ptr */
2095 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2096 /* allocate local 2 (boolean) delete_old */
2097 mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
2099 /* delete_old = FALSE */
2100 mono_mb_emit_icon (mb, 0);
2101 mono_mb_emit_byte (mb, CEE_STLOC_2);
2103 if (sig->ret->type != MONO_TYPE_VOID) {
2104 /* allocate local 3 to store the return value */
2105 mono_mb_add_local (mb, sig->ret);
2108 /* we first do all conversions */
2109 tmp_locals = alloca (sizeof (int) * sig->param_count);
2110 for (i = 0; i < sig->param_count; i ++) {
2111 MonoType *t = sig->params [i];
2112 MonoMarshalSpec *spec = mspecs [i + 1];
2114 argnum = i + sig->hasthis;
2118 case MONO_TYPE_VALUETYPE:
2119 klass = t->data.klass;
2121 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
2122 klass->blittable || klass->enumtype)
2125 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2127 /* store the address of the source into local variable 0 */
2129 mono_mb_emit_ldarg (mb, argnum);
2131 mono_mb_emit_ldarg_addr (mb, argnum);
2133 mono_mb_emit_byte (mb, CEE_STLOC_0);
2135 /* allocate space for the native struct and
2136 * store the address into local variable 1 (dest) */
2137 mono_mb_emit_icon (mb, mono_class_native_size (klass, NULL));
2138 mono_mb_emit_byte (mb, CEE_PREFIX1);
2139 mono_mb_emit_byte (mb, CEE_LOCALLOC);
2140 mono_mb_emit_stloc (mb, tmp_locals [i]);
2143 mono_mb_emit_byte (mb, CEE_LDLOC_0);
2144 mono_mb_emit_byte (mb, CEE_BRFALSE);
2146 mono_mb_emit_i4 (mb, 0);
2150 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2151 mono_mb_emit_byte (mb, CEE_STLOC_1);
2153 /* emit valuetype conversion code */
2154 emit_struct_conv (mb, klass, FALSE);
2157 mono_mb_patch_addr (mb, pos, mb->pos - (pos + 4));
2159 case MONO_TYPE_STRING:
2163 csig->params [argnum] = &mono_defaults.int_class->byval_arg;
2164 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2166 mono_mb_emit_ldarg (mb, argnum);
2167 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2168 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
2171 switch (spec->native) {
2172 case MONO_NATIVE_LPWSTR:
2173 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPWSTR);
2176 g_warning ("marshalling conversion not implemented");
2177 g_assert_not_reached ();
2180 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STR_LPSTR);
2183 mono_mb_emit_stloc (mb, tmp_locals [i]);
2185 case MONO_TYPE_CLASS:
2186 case MONO_TYPE_OBJECT:
2190 csig->params [argnum] = &mono_defaults.int_class->byval_arg;
2191 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2193 if (t->data.klass->delegate) {
2194 mono_mb_emit_ldarg (mb, argnum);
2195 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2196 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
2197 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_DEL_FTN);
2198 mono_mb_emit_stloc (mb, tmp_locals [i]);
2199 } else if (t->data.klass == mono_defaults.stringbuilder_class) {
2200 mono_mb_emit_ldarg (mb, argnum);
2201 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2202 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
2203 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_SB_LPSTR);
2204 mono_mb_emit_stloc (mb, tmp_locals [i]);
2206 mono_mb_emit_ldarg (mb, argnum);
2207 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2208 mono_mb_emit_byte (mb, CEE_MONO_OBJADDR);
2209 /* fixme: convert to what ? */
2210 mono_mb_emit_stloc (mb, tmp_locals [i]);
2214 case MONO_TYPE_ARRAY:
2215 case MONO_TYPE_SZARRAY:
2219 klass = mono_class_from_mono_type (t);
2221 csig->params [argnum] = &mono_defaults.int_class->byval_arg;
2222 tmp_locals [i] = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2224 mono_mb_emit_ldarg (mb, argnum);
2225 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2226 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
2227 if (klass->element_class == mono_defaults.string_class)
2228 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_STRARRAY_STRLPARRAY);
2230 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_ARRAY_LPARRAY);
2231 mono_mb_emit_stloc (mb, tmp_locals [i]);
2236 /* push all arguments */
2239 mono_mb_emit_byte (mb, CEE_LDARG_0);
2241 for (i = 0; i < sig->param_count; i++) {
2242 MonoType *t = sig->params [i];
2244 argnum = i + sig->hasthis;
2247 case MONO_TYPE_BOOLEAN:
2249 g_warning ("byref boolean marshalling not inplemented");
2250 mono_mb_emit_ldarg (mb, argnum);
2265 mono_mb_emit_ldarg (mb, argnum);
2267 case MONO_TYPE_VALUETYPE:
2268 klass = sig->params [i]->data.klass;
2269 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
2270 klass->blittable || klass->enumtype) {
2271 mono_mb_emit_ldarg (mb, argnum);
2274 g_assert (tmp_locals [i]);
2275 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2277 mono_mb_emit_byte (mb, CEE_LDOBJ);
2278 mono_mb_emit_i4 (mb, mono_mb_add_data (mb, klass));
2281 case MONO_TYPE_STRING:
2283 mono_mb_emit_ldarg (mb, argnum);
2285 g_assert (tmp_locals [i]);
2286 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2289 case MONO_TYPE_CLASS:
2290 case MONO_TYPE_OBJECT:
2292 mono_mb_emit_ldarg (mb, argnum);
2294 g_assert (tmp_locals [i]);
2295 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2298 case MONO_TYPE_CHAR:
2299 /* fixme: dont know how to marshal that. We cant simply
2300 * convert it to a one byte UTF8 character, because an
2301 * unicode character may need more that one byte in UTF8 */
2302 mono_mb_emit_ldarg (mb, argnum);
2304 case MONO_TYPE_ARRAY:
2305 case MONO_TYPE_SZARRAY:
2307 mono_mb_emit_ldarg (mb, argnum);
2309 g_assert (tmp_locals [i]);
2310 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2313 case MONO_TYPE_TYPEDBYREF:
2314 case MONO_TYPE_FNPTR:
2316 g_warning ("type 0x%02x unknown", t->type);
2317 g_assert_not_reached ();
2321 /* call the native method */
2322 mono_mb_emit_native_call (mb, csig, method->addr);
2324 /* return the result */
2326 /* we need to convert byref arguments back and free string arrays */
2327 for (i = 0; i < sig->param_count; i++) {
2328 MonoType *t = sig->params [i];
2330 argnum = i + sig->hasthis;
2333 case MONO_TYPE_CLASS:
2334 case MONO_TYPE_OBJECT:
2338 if (t->data.klass == mono_defaults.stringbuilder_class) {
2339 mono_mb_emit_ldarg (mb, argnum);
2340 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2341 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2342 mono_mb_emit_byte (mb, CEE_MONO_PROC2);
2343 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_SB);
2344 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2345 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2346 mono_mb_emit_byte (mb, CEE_MONO_FREE);
2349 case MONO_TYPE_VALUETYPE:
2353 klass = t->data.klass;
2354 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
2355 klass->blittable || klass->enumtype)
2358 /* dst = argument */
2359 mono_mb_emit_ldarg (mb, argnum);
2360 mono_mb_emit_byte (mb, CEE_STLOC_1);
2362 mono_mb_emit_byte (mb, CEE_LDLOC_1);
2363 mono_mb_emit_byte (mb, CEE_BRFALSE);
2365 mono_mb_emit_i4 (mb, 0);
2367 /* src = tmp_locals [i] */
2368 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2369 mono_mb_emit_byte (mb, CEE_STLOC_0);
2371 /* emit valuetype conversion code */
2372 emit_struct_conv (mb, klass, TRUE);
2374 mono_mb_patch_addr (mb, pos, mb->pos - (pos + 4));
2376 case MONO_TYPE_SZARRAY:
2380 klass = mono_class_from_mono_type (t);
2382 if (klass->element_class == mono_defaults.string_class) {
2383 g_assert (tmp_locals [i]);
2384 mono_mb_emit_ldloc (mb, tmp_locals [i]);
2385 mono_mb_emit_ldarg (mb, argnum);
2386 mono_mb_emit_byte (mb, CEE_LDLEN);
2387 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2388 mono_mb_emit_byte (mb, CEE_MONO_PROC2);
2389 mono_mb_emit_byte (mb, MONO_MARSHAL_FREE_ARRAY);
2396 if (!sig->ret->byref) {
2397 MonoMarshalSpec *spec = mspecs [0];
2398 type = sig->ret->type;
2402 case MONO_TYPE_VOID:
2416 /* no conversions necessary */
2418 case MONO_TYPE_BOOLEAN:
2419 /* maybe we need to make sure that it fits within 8 bits */
2421 case MONO_TYPE_VALUETYPE: {
2424 klass = sig->ret->data.klass;
2425 if (klass->enumtype) {
2426 type = sig->ret->data.klass->enum_basetype->type;
2430 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) ||
2434 tmp = mono_mb_add_local (mb, sig->ret);
2436 /* load pointer to returned value type */
2437 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2438 mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
2439 /* store the address of the source into local variable 0 */
2440 mono_mb_emit_byte (mb, CEE_STLOC_0);
2442 mono_mb_emit_ldloc_addr (mb, tmp);
2443 mono_mb_emit_byte (mb, CEE_STLOC_1);
2445 /* emit valuetype conversion code */
2446 emit_struct_conv (mb, sig->ret->data.klass, TRUE);
2448 mono_mb_emit_ldloc (mb, tmp);
2451 case MONO_TYPE_STRING:
2452 mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
2453 mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
2455 switch (spec->native) {
2456 case MONO_NATIVE_LPWSTR:
2457 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPWSTR_STR);
2460 g_warning ("marshalling conversion not implemented");
2461 g_assert_not_reached ();
2464 mono_mb_emit_byte (mb, MONO_MARSHAL_CONV_LPSTR_STR);
2467 case MONO_TYPE_ARRAY:
2468 case MONO_TYPE_SZARRAY:
2469 case MONO_TYPE_CLASS:
2470 case MONO_TYPE_OBJECT:
2471 /* fixme: we need conversions here */
2473 case MONO_TYPE_CHAR:
2474 /* fixme: we need conversions here */
2476 case MONO_TYPE_TYPEDBYREF:
2477 case MONO_TYPE_FNPTR:
2479 g_warning ("return type 0x%02x unknown", sig->ret->type);
2480 g_assert_not_reached ();
2484 mono_mb_emit_byte (mb, CEE_RET);
2486 res = mono_mb_create_method (mb, sig, sig->param_count + 16);
2489 g_hash_table_insert (cache, method, res);
2491 for (i = sig->param_count; i >= 0; i--)
2492 g_free (mspecs [i]);
2499 * generates IL code for StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld)
2502 mono_marshal_get_struct_to_ptr (MonoClass *klass)
2504 MonoMethodBuilder *mb;
2505 static MonoMethod *stoptr = NULL;
2508 g_assert (klass != NULL);
2510 if (klass->str_to_ptr)
2511 return klass->str_to_ptr;
2514 stoptr = mono_find_method_by_name (mono_defaults.marshal_class, "StructureToPtr", 3);
2517 mb = mono_mb_new (klass, stoptr->name, MONO_WRAPPER_UNKNOWN);
2519 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable) {
2520 mono_mb_emit_byte (mb, CEE_LDARG_1);
2521 mono_mb_emit_byte (mb, CEE_LDARG_0);
2522 mono_mb_emit_icon (mb, sizeof (MonoObject));
2523 mono_mb_emit_byte (mb, CEE_ADD);
2524 mono_mb_emit_icon (mb, mono_class_value_size (klass, NULL));
2525 mono_mb_emit_byte (mb, CEE_PREFIX1);
2526 mono_mb_emit_byte (mb, CEE_CPBLK);
2529 /* allocate local 0 (pointer) src_ptr */
2530 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2531 /* allocate local 1 (pointer) dst_ptr */
2532 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2533 /* allocate local 2 (boolean) delete_old */
2534 mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
2535 mono_mb_emit_byte (mb, CEE_LDARG_2);
2536 mono_mb_emit_byte (mb, CEE_STLOC_2);
2538 /* initialize src_ptr to point to the start of object data */
2539 mono_mb_emit_byte (mb, CEE_LDARG_0);
2540 mono_mb_emit_icon (mb, sizeof (MonoObject));
2541 mono_mb_emit_byte (mb, CEE_ADD);
2542 mono_mb_emit_byte (mb, CEE_STLOC_0);
2544 /* initialize dst_ptr */
2545 mono_mb_emit_byte (mb, CEE_LDARG_1);
2546 mono_mb_emit_byte (mb, CEE_STLOC_1);
2548 emit_struct_conv (mb, klass, FALSE);
2551 mono_mb_emit_byte (mb, CEE_RET);
2553 res = mono_mb_create_method (mb, stoptr->signature, 0);
2556 klass->str_to_ptr = res;
2561 * generates IL code for PtrToStructure (IntPtr src, object structure)
2564 mono_marshal_get_ptr_to_struct (MonoClass *klass)
2566 MonoMethodBuilder *mb;
2567 static MonoMethod *ptostr = NULL;
2570 g_assert (klass != NULL);
2572 if (klass->ptr_to_str)
2573 return klass->ptr_to_str;
2576 ptostr = mono_find_method_by_name (mono_defaults.marshal_class, "PtrToStructure", 2);
2579 mb = mono_mb_new (klass, ptostr->name, MONO_WRAPPER_UNKNOWN);
2581 if (((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable) {
2582 mono_mb_emit_byte (mb, CEE_LDARG_1);
2583 mono_mb_emit_icon (mb, sizeof (MonoObject));
2584 mono_mb_emit_byte (mb, CEE_ADD);
2585 mono_mb_emit_byte (mb, CEE_LDARG_0);
2586 mono_mb_emit_icon (mb, mono_class_value_size (klass, NULL));
2587 mono_mb_emit_byte (mb, CEE_PREFIX1);
2588 mono_mb_emit_byte (mb, CEE_CPBLK);
2591 /* allocate local 0 (pointer) src_ptr */
2592 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2593 /* allocate local 1 (pointer) dst_ptr */
2594 mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
2596 /* initialize src_ptr to point to the start of object data */
2597 mono_mb_emit_byte (mb, CEE_LDARG_0);
2598 mono_mb_emit_byte (mb, CEE_STLOC_0);
2600 /* initialize dst_ptr */
2601 mono_mb_emit_byte (mb, CEE_LDARG_1);
2602 mono_mb_emit_icon (mb, sizeof (MonoObject));
2603 mono_mb_emit_byte (mb, CEE_ADD);
2604 mono_mb_emit_byte (mb, CEE_STLOC_1);
2606 emit_struct_conv (mb, klass, TRUE);
2609 mono_mb_emit_byte (mb, CEE_RET);
2611 res = mono_mb_create_method (mb, ptostr->signature, 0);
2614 klass->ptr_to_str = res;
2618 /* FIXME: on win32 we should probably use GlobalAlloc(). */
2620 mono_marshal_alloc (gpointer size)
2622 MONO_ARCH_SAVE_REGS;
2624 return g_try_malloc ((gulong)size);
2628 mono_marshal_free (gpointer ptr)
2630 MONO_ARCH_SAVE_REGS;
2636 mono_marshal_free_array (gpointer *ptr, int size) {
2639 for (i = 0; i < size; i++)
2645 mono_marshal_realloc (gpointer ptr, gpointer size)
2647 MONO_ARCH_SAVE_REGS;
2649 return g_try_realloc (ptr, (gulong)size);
2653 mono_marshal_string_array (MonoArray *array)
2661 len = mono_array_length (array);
2663 result = g_malloc (sizeof (char *) * (len + 1));
2664 for (i = 0; i < len; ++i) {
2665 MonoString *s = (MonoString *)mono_array_get (array, gpointer, i);
2666 result [i] = s ? mono_string_to_utf8 (s): NULL;
2668 /* null terminate the array */
2675 ves_icall_System_Runtime_InteropServices_Marshal_copy_to_unmanaged (MonoArray *src, gint32 start_index,
2676 gpointer dest, gint32 length)
2681 MONO_ARCH_SAVE_REGS;
2683 MONO_CHECK_ARG_NULL (src);
2684 MONO_CHECK_ARG_NULL (dest);
2686 g_assert (src->obj.vtable->klass->rank == 1);
2687 g_assert (start_index >= 0);
2688 g_assert (length >= 0);
2689 g_assert (start_index + length <= mono_array_length (src));
2691 element_size = mono_array_element_size (src->obj.vtable->klass);
2693 source_addr = mono_array_addr_with_size (src, element_size, start_index);
2695 memcpy (dest, source_addr, length * element_size);
2699 ves_icall_System_Runtime_InteropServices_Marshal_copy_from_unmanaged (gpointer src, gint32 start_index,
2700 MonoArray *dest, gint32 length)
2705 MONO_ARCH_SAVE_REGS;
2707 MONO_CHECK_ARG_NULL (src);
2708 MONO_CHECK_ARG_NULL (dest);
2710 g_assert (dest->obj.vtable->klass->rank == 1);
2711 g_assert (start_index >= 0);
2712 g_assert (length >= 0);
2713 g_assert (start_index + length <= mono_array_length (dest));
2715 element_size = mono_array_element_size (dest->obj.vtable->klass);
2717 dest_addr = mono_array_addr_with_size (dest, element_size, start_index);
2719 memcpy (dest_addr, src, length * element_size);
2723 ves_icall_System_Runtime_InteropServices_Marshal_ReadIntPtr (gpointer ptr, gint32 offset)
2727 MONO_ARCH_SAVE_REGS;
2729 return *(gpointer*)(p + offset);
2733 ves_icall_System_Runtime_InteropServices_Marshal_ReadByte (gpointer ptr, gint32 offset)
2737 MONO_ARCH_SAVE_REGS;
2739 return *(unsigned char*)(p + offset);
2743 ves_icall_System_Runtime_InteropServices_Marshal_ReadInt16 (gpointer ptr, gint32 offset)
2747 MONO_ARCH_SAVE_REGS;
2749 return *(gint16*)(p + offset);
2753 ves_icall_System_Runtime_InteropServices_Marshal_ReadInt32 (gpointer ptr, gint32 offset)
2757 MONO_ARCH_SAVE_REGS;
2759 return *(gint32*)(p + offset);
2763 ves_icall_System_Runtime_InteropServices_Marshal_ReadInt64 (gpointer ptr, gint32 offset)
2767 MONO_ARCH_SAVE_REGS;
2769 return *(gint64*)(p + offset);
2773 ves_icall_System_Runtime_InteropServices_Marshal_WriteByte (gpointer ptr, gint32 offset, unsigned char val)
2777 MONO_ARCH_SAVE_REGS;
2779 *(unsigned char*)(p + offset) = val;
2783 ves_icall_System_Runtime_InteropServices_Marshal_WriteIntPtr (gpointer ptr, gint32 offset, gpointer val)
2787 MONO_ARCH_SAVE_REGS;
2789 *(gpointer*)(p + offset) = val;
2793 ves_icall_System_Runtime_InteropServices_Marshal_WriteInt16 (gpointer ptr, gint32 offset, gint16 val)
2797 MONO_ARCH_SAVE_REGS;
2799 *(gint16*)(p + offset) = val;
2803 ves_icall_System_Runtime_InteropServices_Marshal_WriteInt32 (gpointer ptr, gint32 offset, gint32 val)
2807 MONO_ARCH_SAVE_REGS;
2809 *(gint32*)(p + offset) = val;
2813 ves_icall_System_Runtime_InteropServices_Marshal_WriteInt64 (gpointer ptr, gint32 offset, gint64 val)
2817 MONO_ARCH_SAVE_REGS;
2819 *(gint64*)(p + offset) = val;
2823 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi (char *ptr)
2825 MONO_ARCH_SAVE_REGS;
2827 return mono_string_new (mono_domain_get (), ptr);
2831 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringAnsi_len (char *ptr, gint32 len)
2833 MONO_ARCH_SAVE_REGS;
2835 return mono_string_new_len (mono_domain_get (), ptr, len);
2839 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni (guint16 *ptr)
2841 MonoDomain *domain = mono_domain_get ();
2845 MONO_ARCH_SAVE_REGS;
2850 return mono_string_new_utf16 (domain, ptr, len);
2854 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringUni_len (guint16 *ptr, gint32 len)
2856 MonoDomain *domain = mono_domain_get ();
2858 MONO_ARCH_SAVE_REGS;
2860 return mono_string_new_utf16 (domain, ptr, len);
2864 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStringBSTR (gpointer ptr)
2866 MONO_ARCH_SAVE_REGS;
2868 g_warning ("PtrToStringBSTR not implemented");
2869 g_assert_not_reached ();
2875 ves_icall_System_Runtime_InteropServices_Marshal_GetLastWin32Error (void)
2877 MONO_ARCH_SAVE_REGS;
2879 return (GetLastError ());
2883 ves_icall_System_Runtime_InteropServices_Marshal_SizeOf (MonoReflectionType *rtype)
2887 MONO_ARCH_SAVE_REGS;
2889 MONO_CHECK_ARG_NULL (rtype);
2891 klass = mono_class_from_mono_type (rtype->type);
2893 return mono_class_native_size (klass, NULL);
2897 ves_icall_System_Runtime_InteropServices_Marshal_StructureToPtr (MonoObject *obj, gpointer dst, MonoBoolean delete_old)
2902 MONO_ARCH_SAVE_REGS;
2904 MONO_CHECK_ARG_NULL (obj);
2905 MONO_CHECK_ARG_NULL (dst);
2907 method = mono_marshal_get_struct_to_ptr (obj->vtable->klass);
2911 pa [2] = &delete_old;
2913 mono_runtime_invoke (method, NULL, pa, NULL);
2917 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (gpointer src, MonoObject *dst)
2922 MONO_ARCH_SAVE_REGS;
2924 MONO_CHECK_ARG_NULL (src);
2925 MONO_CHECK_ARG_NULL (dst);
2927 method = mono_marshal_get_ptr_to_struct (dst->vtable->klass);
2932 mono_runtime_invoke (method, NULL, pa, NULL);
2936 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type (gpointer src, MonoReflectionType *type)
2938 MonoDomain *domain = mono_domain_get ();
2941 MONO_ARCH_SAVE_REGS;
2943 MONO_CHECK_ARG_NULL (src);
2944 MONO_CHECK_ARG_NULL (type);
2946 res = mono_object_new (domain, mono_class_from_mono_type (type->type));
2948 ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (src, res);
2954 ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *type, MonoString *field_name)
2956 MonoMarshalType *info;
2961 MONO_ARCH_SAVE_REGS;
2963 MONO_CHECK_ARG_NULL (type);
2964 MONO_CHECK_ARG_NULL (field_name);
2966 fname = mono_string_to_utf8 (field_name);
2967 klass = mono_class_from_mono_type (type->type);
2969 info = mono_marshal_load_type_info (klass);
2971 for (i = 0; i < klass->field.count; ++i) {
2972 if (*fname == *klass->fields [i].name &&
2973 strcmp (fname, klass->fields [i].name) == 0)
2978 mono_assert (i < klass->field.count);
2980 return info->fields [i].offset;
2984 ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString *string)
2986 MONO_ARCH_SAVE_REGS;
2988 return mono_string_to_utf8 (string);
2992 ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalUni (MonoString *string)
2994 MONO_ARCH_SAVE_REGS;
2996 return g_memdup (mono_string_chars (string), mono_string_length (string)*2);
3000 mono_struct_delete_old (MonoClass *klass, char *ptr)
3002 MonoMarshalType *info;
3005 info = mono_marshal_load_type_info (klass);
3007 for (i = 0; i < info->num_fields; i++) {
3008 MonoMarshalNative ntype;
3009 MonoMarshalConv conv;
3010 MonoType *ftype = info->fields [i].field->type;
3013 if (ftype->attrs & FIELD_ATTRIBUTE_STATIC)
3016 ntype = mono_type_to_unmanaged (ftype, info->fields [i].mspec, TRUE,
3017 klass->unicode, &conv);
3019 cpos = ptr + info->fields [i].offset;
3022 case MONO_MARSHAL_CONV_NONE:
3023 if (MONO_TYPE_ISSTRUCT (ftype)) {
3024 mono_struct_delete_old (ftype->data.klass, cpos);
3028 case MONO_MARSHAL_CONV_STR_LPWSTR:
3029 case MONO_MARSHAL_CONV_STR_LPSTR:
3030 case MONO_MARSHAL_CONV_STR_LPTSTR:
3031 case MONO_MARSHAL_CONV_STR_BSTR:
3032 case MONO_MARSHAL_CONV_STR_ANSIBSTR:
3033 case MONO_MARSHAL_CONV_STR_TBSTR:
3034 g_free (*(gpointer *)cpos);
3043 ves_icall_System_Runtime_InteropServices_Marshal_DestroyStructure (gpointer src, MonoReflectionType *type)
3047 MONO_ARCH_SAVE_REGS;
3049 MONO_CHECK_ARG_NULL (src);
3050 MONO_CHECK_ARG_NULL (type);
3052 klass = mono_class_from_mono_type (type->type);
3054 mono_struct_delete_old (klass, (char *)src);