Remove obsolete Microsoft.Vsa and Microsoft.JScript
[mono-project/dkf.git] / mono / mini / jit-icalls.c
blob81c04514b5abe301205e20bdc9d55a4f17ac1b1e
1 /*
2 * jit-icalls.c: internal calls used by the JIT
4 * Author:
5 * Dietmar Maurer (dietmar@ximian.com)
6 * Paolo Molaro (lupus@ximian.com)
8 * (C) 2002 Ximian, Inc.
9 */
10 #include <config.h>
11 #include <math.h>
12 #include <limits.h>
13 #ifdef HAVE_ALLOCA_H
14 #include <alloca.h>
15 #endif
17 #include "jit-icalls.h"
19 void*
20 mono_ldftn (MonoMethod *method)
22 gpointer addr;
24 MONO_ARCH_SAVE_REGS;
26 addr = mono_create_jump_trampoline (mono_domain_get (), method, FALSE);
28 return mono_create_ftnptr (mono_domain_get (), addr);
31 static void*
32 ldvirtfn_internal (MonoObject *obj, MonoMethod *method, gboolean gshared)
34 MonoMethod *res;
36 MONO_ARCH_SAVE_REGS;
38 if (obj == NULL)
39 mono_raise_exception (mono_get_exception_null_reference ());
41 res = mono_object_get_virtual_method (obj, method);
43 if (gshared && method->is_inflated && mono_method_get_context (method)->method_inst) {
44 MonoGenericContext context = { NULL, NULL };
46 if (res->klass->generic_class)
47 context.class_inst = res->klass->generic_class->context.class_inst;
48 else if (res->klass->generic_container)
49 context.class_inst = res->klass->generic_container->context.class_inst;
50 context.method_inst = mono_method_get_context (method)->method_inst;
52 res = mono_class_inflate_generic_method (res, &context);
55 /* An rgctx wrapper is added by the trampolines no need to do it here */
57 return mono_ldftn (res);
60 void*
61 mono_ldvirtfn (MonoObject *obj, MonoMethod *method)
63 return ldvirtfn_internal (obj, method, FALSE);
66 void*
67 mono_ldvirtfn_gshared (MonoObject *obj, MonoMethod *method)
69 return ldvirtfn_internal (obj, method, TRUE);
72 void
73 mono_helper_stelem_ref_check (MonoArray *array, MonoObject *val)
75 MONO_ARCH_SAVE_REGS;
77 if (val && !mono_object_isinst (val, array->obj.vtable->klass->element_class))
78 mono_raise_exception (mono_get_exception_array_type_mismatch ());
81 #ifndef MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS
83 gint64
84 mono_llmult (gint64 a, gint64 b)
86 /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
87 return a * b;
90 guint64
91 mono_llmult_ovf_un (guint64 a, guint64 b)
93 guint32 al = a;
94 guint32 ah = a >> 32;
95 guint32 bl = b;
96 guint32 bh = b >> 32;
97 guint64 res, t1;
99 MONO_ARCH_SAVE_REGS;
101 // fixme: this is incredible slow
103 if (ah && bh)
104 goto raise_exception;
106 res = (guint64)al * (guint64)bl;
108 t1 = (guint64)ah * (guint64)bl + (guint64)al * (guint64)bh;
110 if (t1 > 0xffffffff)
111 goto raise_exception;
113 res += ((guint64)t1) << 32;
115 return res;
117 raise_exception:
118 mono_raise_exception (mono_get_exception_overflow ());
119 return 0;
122 guint64
123 mono_llmult_ovf (gint64 a, gint64 b)
125 guint32 al = a;
126 gint32 ah = a >> 32;
127 guint32 bl = b;
128 gint32 bh = b >> 32;
130 Use Karatsuba algorithm where:
131 a*b is: AhBh(R^2+R)+(Ah-Al)(Bl-Bh)R+AlBl(R+1)
132 where Ah is the "high half" (most significant 32 bits) of a and
133 where Al is the "low half" (least significant 32 bits) of a and
134 where Bh is the "high half" of b and Bl is the "low half" and
135 where R is the Radix or "size of the half" (in our case 32 bits)
137 Note, for the product of two 64 bit numbers to fit into a 64
138 result, ah and/or bh must be 0. This will save us from doing
139 the AhBh term at all.
141 Also note that we refactor so that we don't overflow 64 bits with
142 intermediate results. So we use [(Ah-Al)(Bl-Bh)+AlBl]R+AlBl
145 gint64 res, t1;
146 gint32 sign;
148 MONO_ARCH_SAVE_REGS;
150 /* need to work with absoulte values, so find out what the
151 resulting sign will be and convert any negative numbers
152 from two's complement
154 sign = ah ^ bh;
155 if (ah < 0) {
156 if (((guint32)ah == 0x80000000) && (al == 0)) {
157 /* This has no two's complement */
158 if (b == 0)
159 return 0;
160 else if (b == 1)
161 return a;
162 else
163 goto raise_exception;
166 /* flip the bits and add 1 */
167 ah ^= ~0;
168 if (al == 0)
169 ah += 1;
170 else {
171 al ^= ~0;
172 al +=1;
176 if (bh < 0) {
177 if (((guint32)bh == 0x80000000) && (bl == 0)) {
178 /* This has no two's complement */
179 if (a == 0)
180 return 0;
181 else if (a == 1)
182 return b;
183 else
184 goto raise_exception;
187 /* flip the bits and add 1 */
188 bh ^= ~0;
189 if (bl == 0)
190 bh += 1;
191 else {
192 bl ^= ~0;
193 bl +=1;
197 /* we overflow for sure if both upper halves are greater
198 than zero because we would need to shift their
199 product 64 bits to the left and that will not fit
200 in a 64 bit result */
201 if (ah && bh)
202 goto raise_exception;
203 if ((gint64)((gint64)ah * (gint64)bl) > (gint64)0x80000000 || (gint64)((gint64)al * (gint64)bh) > (gint64)0x80000000)
204 goto raise_exception;
206 /* do the AlBl term first */
207 t1 = (gint64)al * (gint64)bl;
209 res = t1;
211 /* now do the [(Ah-Al)(Bl-Bh)+AlBl]R term */
212 t1 += (gint64)(ah - al) * (gint64)(bl - bh);
213 /* check for overflow */
214 t1 <<= 32;
215 if (t1 > (0x7FFFFFFFFFFFFFFFLL - res))
216 goto raise_exception;
218 res += t1;
220 if (res < 0)
221 goto raise_exception;
223 if (sign < 0)
224 return -res;
225 else
226 return res;
228 raise_exception:
229 mono_raise_exception (mono_get_exception_overflow ());
230 return 0;
233 #if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_DIV)
235 gint32
236 mono_idiv (gint32 a, gint32 b)
238 MONO_ARCH_SAVE_REGS;
240 #ifdef MONO_ARCH_NEED_DIV_CHECK
241 if (!b)
242 mono_raise_exception (mono_get_exception_divide_by_zero ());
243 else if (b == -1 && a == (0x80000000))
244 mono_raise_exception (mono_get_exception_arithmetic ());
245 #endif
246 return a / b;
249 guint32
250 mono_idiv_un (guint32 a, guint32 b)
252 MONO_ARCH_SAVE_REGS;
254 #ifdef MONO_ARCH_NEED_DIV_CHECK
255 if (!b)
256 mono_raise_exception (mono_get_exception_divide_by_zero ());
257 #endif
258 return a / b;
261 gint32
262 mono_irem (gint32 a, gint32 b)
264 MONO_ARCH_SAVE_REGS;
266 #ifdef MONO_ARCH_NEED_DIV_CHECK
267 if (!b)
268 mono_raise_exception (mono_get_exception_divide_by_zero ());
269 else if (b == -1 && a == (0x80000000))
270 mono_raise_exception (mono_get_exception_arithmetic ());
271 #endif
273 return a % b;
276 guint32
277 mono_irem_un (guint32 a, guint32 b)
279 MONO_ARCH_SAVE_REGS;
281 #ifdef MONO_ARCH_NEED_DIV_CHECK
282 if (!b)
283 mono_raise_exception (mono_get_exception_divide_by_zero ());
284 #endif
285 return a % b;
288 #endif
290 #if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_EMULATE_MUL_OVF)
292 gint32
293 mono_imul (gint32 a, gint32 b)
295 MONO_ARCH_SAVE_REGS;
297 return a * b;
300 gint32
301 mono_imul_ovf (gint32 a, gint32 b)
303 gint64 res;
305 MONO_ARCH_SAVE_REGS;
307 res = (gint64)a * (gint64)b;
309 if ((res > 0x7fffffffL) || (res < -2147483648LL))
310 mono_raise_exception (mono_get_exception_overflow ());
312 return res;
315 gint32
316 mono_imul_ovf_un (guint32 a, guint32 b)
318 guint64 res;
320 MONO_ARCH_SAVE_REGS;
322 res = (guint64)a * (guint64)b;
324 if ((res >> 32))
325 mono_raise_exception (mono_get_exception_overflow ());
327 return res;
329 #endif
331 #if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT)
332 double
333 mono_fdiv (double a, double b)
335 MONO_ARCH_SAVE_REGS;
337 return a / b;
339 #endif
341 gint64
342 mono_lldiv (gint64 a, gint64 b)
344 MONO_ARCH_SAVE_REGS;
346 #ifdef MONO_ARCH_NEED_DIV_CHECK
347 if (!b)
348 mono_raise_exception (mono_get_exception_divide_by_zero ());
349 else if (b == -1 && a == (-9223372036854775807LL - 1LL))
350 mono_raise_exception (mono_get_exception_arithmetic ());
351 #endif
352 return a / b;
355 gint64
356 mono_llrem (gint64 a, gint64 b)
358 MONO_ARCH_SAVE_REGS;
360 #ifdef MONO_ARCH_NEED_DIV_CHECK
361 if (!b)
362 mono_raise_exception (mono_get_exception_divide_by_zero ());
363 else if (b == -1 && a == (-9223372036854775807LL - 1LL))
364 mono_raise_exception (mono_get_exception_arithmetic ());
365 #endif
366 return a % b;
369 guint64
370 mono_lldiv_un (guint64 a, guint64 b)
372 MONO_ARCH_SAVE_REGS;
374 #ifdef MONO_ARCH_NEED_DIV_CHECK
375 if (!b)
376 mono_raise_exception (mono_get_exception_divide_by_zero ());
377 #endif
378 return a / b;
381 guint64
382 mono_llrem_un (guint64 a, guint64 b)
384 MONO_ARCH_SAVE_REGS;
386 #ifdef MONO_ARCH_NEED_DIV_CHECK
387 if (!b)
388 mono_raise_exception (mono_get_exception_divide_by_zero ());
389 #endif
390 return a % b;
393 #endif
395 #ifndef MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
397 guint64
398 mono_lshl (guint64 a, gint32 shamt)
400 guint64 res;
402 /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
403 res = a << shamt;
405 /*printf ("TESTL %lld << %d = %lld\n", a, shamt, res);*/
407 return res;
410 guint64
411 mono_lshr_un (guint64 a, gint32 shamt)
413 guint64 res;
415 /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
416 res = a >> shamt;
418 /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
420 return res;
423 gint64
424 mono_lshr (gint64 a, gint32 shamt)
426 gint64 res;
428 /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
429 res = a >> shamt;
431 /*printf ("TESTR %lld >> %d = %lld\n", a, shamt, res);*/
433 return res;
436 #endif
438 #ifdef MONO_ARCH_SOFT_FLOAT
440 double
441 mono_fsub (double a, double b)
443 return a - b;
446 double
447 mono_fadd (double a, double b)
449 return a + b;
452 double
453 mono_fmul (double a, double b)
455 return a * b;
458 double
459 mono_fneg (double a)
461 return -a;
464 double
465 mono_fconv_r4 (double a)
467 return (float)a;
470 double
471 mono_conv_to_r8 (int a)
473 return (double)a;
476 double
477 mono_conv_to_r4 (int a)
479 return (double)(float)a;
482 gint8
483 mono_fconv_i1 (double a)
485 return (gint8)a;
488 gint16
489 mono_fconv_i2 (double a)
491 return (gint16)a;
494 gint32
495 mono_fconv_i4 (double a)
497 return (gint32)a;
500 guint8
501 mono_fconv_u1 (double a)
503 return (guint8)a;
506 guint16
507 mono_fconv_u2 (double a)
509 return (guint16)a;
512 gboolean
513 mono_fcmp_eq (double a, double b)
515 return a == b;
518 gboolean
519 mono_fcmp_ge (double a, double b)
521 return a >= b;
524 gboolean
525 mono_fcmp_gt (double a, double b)
527 return a > b;
530 gboolean
531 mono_fcmp_le (double a, double b)
533 return a <= b;
536 gboolean
537 mono_fcmp_lt (double a, double b)
539 return a < b;
542 gboolean
543 mono_fcmp_ne_un (double a, double b)
545 return isunordered (a, b) || a != b;
548 gboolean
549 mono_fcmp_ge_un (double a, double b)
551 return isunordered (a, b) || a >= b;
554 gboolean
555 mono_fcmp_gt_un (double a, double b)
557 return isunordered (a, b) || a > b;
560 gboolean
561 mono_fcmp_le_un (double a, double b)
563 return isunordered (a, b) || a <= b;
566 gboolean
567 mono_fcmp_lt_un (double a, double b)
569 return isunordered (a, b) || a < b;
572 gboolean
573 mono_fceq (double a, double b)
575 return a == b;
578 gboolean
579 mono_fcgt (double a, double b)
581 return a > b;
584 gboolean
585 mono_fcgt_un (double a, double b)
587 return isunordered (a, b) || a > b;
590 gboolean
591 mono_fclt (double a, double b)
593 return a < b;
596 gboolean
597 mono_fclt_un (double a, double b)
599 return isunordered (a, b) || a < b;
602 gboolean
603 mono_isfinite (double a)
605 #ifdef HAVE_ISFINITE
606 return isfinite (a);
607 #else
608 g_assert_not_reached ();
609 return TRUE;
610 #endif
613 double
614 mono_fload_r4 (float *ptr)
616 return *ptr;
619 void
620 mono_fstore_r4 (double val, float *ptr)
622 *ptr = (float)val;
625 /* returns the integer bitpattern that is passed in the regs or stack */
626 guint32
627 mono_fload_r4_arg (double val)
629 float v = (float)val;
630 return *(guint32*)&v;
633 #endif
635 MonoArray *
636 mono_array_new_va (MonoMethod *cm, ...)
638 MonoDomain *domain = mono_domain_get ();
639 va_list ap;
640 uintptr_t *lengths;
641 intptr_t *lower_bounds;
642 int pcount;
643 int rank;
644 int i, d;
646 MONO_ARCH_SAVE_REGS;
648 pcount = mono_method_signature (cm)->param_count;
649 rank = cm->klass->rank;
651 va_start (ap, cm);
653 lengths = alloca (sizeof (uintptr_t) * pcount);
654 for (i = 0; i < pcount; ++i)
655 lengths [i] = d = va_arg(ap, int);
657 if (rank == pcount) {
658 /* Only lengths provided. */
659 if (cm->klass->byval_arg.type == MONO_TYPE_ARRAY) {
660 lower_bounds = alloca (sizeof (intptr_t) * rank);
661 memset (lower_bounds, 0, sizeof (intptr_t) * rank);
662 } else {
663 lower_bounds = NULL;
665 } else {
666 g_assert (pcount == (rank * 2));
667 /* lower bounds are first. */
668 lower_bounds = (intptr_t*)lengths;
669 lengths += rank;
671 va_end(ap);
673 return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
676 /* Specialized version of mono_array_new_va () which avoids varargs */
677 MonoArray *
678 mono_array_new_1 (MonoMethod *cm, guint32 length)
680 MonoDomain *domain = mono_domain_get ();
681 uintptr_t lengths [1];
682 intptr_t *lower_bounds;
683 int pcount;
684 int rank;
686 MONO_ARCH_SAVE_REGS;
688 pcount = mono_method_signature (cm)->param_count;
689 rank = cm->klass->rank;
691 lengths [0] = length;
693 g_assert (rank == pcount);
695 if (cm->klass->byval_arg.type == MONO_TYPE_ARRAY) {
696 lower_bounds = alloca (sizeof (intptr_t) * rank);
697 memset (lower_bounds, 0, sizeof (intptr_t) * rank);
698 } else {
699 lower_bounds = NULL;
702 return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
705 MonoArray *
706 mono_array_new_2 (MonoMethod *cm, guint32 length1, guint32 length2)
708 MonoDomain *domain = mono_domain_get ();
709 uintptr_t lengths [2];
710 intptr_t *lower_bounds;
711 int pcount;
712 int rank;
714 MONO_ARCH_SAVE_REGS;
716 pcount = mono_method_signature (cm)->param_count;
717 rank = cm->klass->rank;
719 lengths [0] = length1;
720 lengths [1] = length2;
722 g_assert (rank == pcount);
724 if (cm->klass->byval_arg.type == MONO_TYPE_ARRAY) {
725 lower_bounds = alloca (sizeof (intptr_t) * rank);
726 memset (lower_bounds, 0, sizeof (intptr_t) * rank);
727 } else {
728 lower_bounds = NULL;
731 return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
734 MonoArray *
735 mono_array_new_3 (MonoMethod *cm, guint32 length1, guint32 length2, guint32 length3)
737 MonoDomain *domain = mono_domain_get ();
738 uintptr_t lengths [3];
739 intptr_t *lower_bounds;
740 int pcount;
741 int rank;
743 MONO_ARCH_SAVE_REGS;
745 pcount = mono_method_signature (cm)->param_count;
746 rank = cm->klass->rank;
748 lengths [0] = length1;
749 lengths [1] = length2;
750 lengths [2] = length3;
752 g_assert (rank == pcount);
754 if (cm->klass->byval_arg.type == MONO_TYPE_ARRAY) {
755 lower_bounds = alloca (sizeof (intptr_t) * rank);
756 memset (lower_bounds, 0, sizeof (intptr_t) * rank);
757 } else {
758 lower_bounds = NULL;
761 return mono_array_new_full (domain, cm->klass, lengths, lower_bounds);
764 gpointer
765 mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
767 MonoVTable *vtable;
768 gpointer addr;
770 MONO_ARCH_SAVE_REGS;
772 //printf ("SFLDA0 %s.%s::%s %d\n", field->parent->name_space, field->parent->name, field->name, field->offset, field->parent->inited);
774 mono_class_init (field->parent);
776 vtable = mono_class_vtable_full (domain, field->parent, TRUE);
777 if (!vtable->initialized)
778 mono_runtime_class_init (vtable);
780 //printf ("SFLDA1 %p\n", (char*)vtable->data + field->offset);
782 if (domain->special_static_fields && (addr = g_hash_table_lookup (domain->special_static_fields, field)))
783 addr = mono_get_special_static_data (GPOINTER_TO_UINT (addr));
784 else
785 addr = (char*)vtable->data + field->offset;
787 return addr;
790 gpointer
791 mono_ldtoken_wrapper (MonoImage *image, int token, MonoGenericContext *context)
793 MonoClass *handle_class;
794 gpointer res;
796 MONO_ARCH_SAVE_REGS;
797 res = mono_ldtoken (image, token, &handle_class, context);
798 mono_class_init (handle_class);
800 return res;
803 gpointer
804 mono_ldtoken_wrapper_generic_shared (MonoImage *image, int token, MonoMethod *method)
806 MonoMethodSignature *sig = mono_method_signature (method);
807 MonoGenericContext *generic_context;
809 if (sig->is_inflated) {
810 generic_context = mono_method_get_context (method);
811 } else {
812 MonoGenericContainer *generic_container = mono_method_get_generic_container (method);
813 g_assert (generic_container);
814 generic_context = &generic_container->context;
817 return mono_ldtoken_wrapper (image, token, generic_context);
820 guint64
821 mono_fconv_u8 (double v)
823 return (guint64)v;
826 #ifdef MONO_ARCH_EMULATE_FCONV_TO_I8
827 gint64
828 mono_fconv_i8 (double v)
830 /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
831 return (gint64)v;
833 #endif
835 guint32
836 mono_fconv_u4 (double v)
838 /* no need, no exceptions: MONO_ARCH_SAVE_REGS;*/
839 return (guint32)v;
842 #ifndef HAVE_TRUNC
843 /* Solaris doesn't have trunc */
844 #ifdef HAVE_AINTL
845 extern long double aintl (long double);
846 #define trunc aintl
847 #else
848 /* FIXME: This means we will never throw overflow exceptions */
849 #define trunc(v) res
850 #endif
851 #endif /* HAVE_TRUNC */
853 gint64
854 mono_fconv_ovf_i8 (double v)
856 gint64 res;
858 MONO_ARCH_SAVE_REGS;
860 res = (gint64)v;
862 if (isnan(v) || trunc (v) != res) {
863 mono_raise_exception (mono_get_exception_overflow ());
865 return res;
868 guint64
869 mono_fconv_ovf_u8 (double v)
871 guint64 res;
873 MONO_ARCH_SAVE_REGS;
875 * The soft-float implementation of some ARM devices have a buggy guin64 to double
876 * conversion that it looses precision even when the integer if fully representable
877 * as a double.
879 * This was found with 4294967295ull, converting to double and back looses one bit of precision.
881 * To work around this issue we test for value boundaries instead.
883 #if defined(__arm__) && MONO_ARCH_SOFT_FLOAT
884 if (isnan (v) || !(v >= -0.5 && v <= ULLONG_MAX+0.5)) {
885 mono_raise_exception (mono_get_exception_overflow ());
887 res = (guint64)v;
888 #else
889 res = (guint64)v;
890 if (isnan(v) || trunc (v) != res) {
891 mono_raise_exception (mono_get_exception_overflow ());
893 #endif
894 return res;
897 #ifdef MONO_ARCH_EMULATE_LCONV_TO_R8
898 double
899 mono_lconv_to_r8 (gint64 a)
901 return (double)a;
903 #endif
905 #ifdef MONO_ARCH_EMULATE_LCONV_TO_R4
906 float
907 mono_lconv_to_r4 (gint64 a)
909 return (float)a;
911 #endif
913 #ifdef MONO_ARCH_EMULATE_CONV_R8_UN
914 double
915 mono_conv_to_r8_un (guint32 a)
917 return (double)a;
919 #endif
921 #ifdef MONO_ARCH_EMULATE_LCONV_TO_R8_UN
922 double
923 mono_lconv_to_r8_un (guint64 a)
925 return (double)a;
927 #endif
929 gpointer
930 mono_helper_compile_generic_method (MonoObject *obj, MonoMethod *method, gpointer *this_arg)
932 MonoMethod *vmethod;
933 gpointer addr;
934 MonoGenericContext *context = mono_method_get_context (method);
936 mono_jit_stats.generic_virtual_invocations++;
938 if (obj == NULL)
939 mono_raise_exception (mono_get_exception_null_reference ());
940 vmethod = mono_object_get_virtual_method (obj, method);
941 g_assert (!vmethod->klass->generic_container);
942 g_assert (!vmethod->klass->generic_class || !vmethod->klass->generic_class->context.class_inst->is_open);
943 g_assert (!context->method_inst || !context->method_inst->is_open);
945 addr = mono_compile_method (vmethod);
947 if (mono_method_needs_static_rgctx_invoke (vmethod, FALSE))
948 addr = mono_create_static_rgctx_trampoline (vmethod, addr);
950 /* Since this is a virtual call, have to unbox vtypes */
951 if (obj->vtable->klass->valuetype)
952 *this_arg = mono_object_unbox (obj);
953 else
954 *this_arg = obj;
956 return addr;
959 MonoString*
960 mono_helper_ldstr (MonoImage *image, guint32 idx)
962 return mono_ldstr (mono_domain_get (), image, idx);
965 MonoString*
966 mono_helper_ldstr_mscorlib (guint32 idx)
968 return mono_ldstr (mono_domain_get (), mono_defaults.corlib, idx);
971 MonoObject*
972 mono_helper_newobj_mscorlib (guint32 idx)
974 MonoClass *klass = mono_class_get (mono_defaults.corlib, MONO_TOKEN_TYPE_DEF | idx);
976 g_assert (klass);
978 return mono_object_new (mono_domain_get (), klass);
982 * On some architectures, gdb doesn't like encountering the cpu breakpoint instructions
983 * in generated code. So instead we emit a call to this function and place a gdb
984 * breakpoint here.
986 void
987 mono_break (void)
991 MonoException *
992 mono_create_corlib_exception_0 (guint32 token)
994 return mono_exception_from_token (mono_defaults.corlib, token);
997 MonoException *
998 mono_create_corlib_exception_1 (guint32 token, MonoString *arg)
1000 return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg, NULL);
1003 MonoException *
1004 mono_create_corlib_exception_2 (guint32 token, MonoString *arg1, MonoString *arg2)
1006 return mono_exception_from_token_two_strings (mono_defaults.corlib, token, arg1, arg2);
1009 MonoObject*
1010 mono_object_castclass (MonoObject *obj, MonoClass *klass)
1012 MonoJitTlsData *jit_tls = NULL;
1014 if (mini_get_debug_options ()->better_cast_details) {
1015 jit_tls = TlsGetValue (mono_jit_tls_id);
1016 jit_tls->class_cast_from = NULL;
1019 if (!obj)
1020 return NULL;
1022 if (mono_object_isinst (obj, klass))
1023 return obj;
1025 if (mini_get_debug_options ()->better_cast_details) {
1026 jit_tls->class_cast_from = obj->vtable->klass;
1027 jit_tls->class_cast_to = klass;
1030 mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
1031 "System", "InvalidCastException"));
1033 return NULL;
1036 gpointer
1037 mono_get_native_calli_wrapper (MonoImage *image, MonoMethodSignature *sig, gpointer func)
1039 MonoMarshalSpec **mspecs;
1040 MonoMethodPInvoke piinfo;
1041 MonoMethod *m;
1043 mspecs = g_new0 (MonoMarshalSpec*, sig->param_count + 1);
1044 memset (&piinfo, 0, sizeof (piinfo));
1046 m = mono_marshal_get_native_func_wrapper (image, sig, &piinfo, mspecs, func);
1048 return mono_compile_method (m);