- case CEE_MONO_FUNC1:
- ADD_CODE(&td, MINT_MONO_CONV1);
- ADD_CODE(&td, *(td.ip + 1));
- td.ip += 2;
- SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I);
- break;
- case CEE_MONO_PROC2:
- CHECK_STACK (&td, 2);
- ADD_CODE(&td, MINT_MONO_CONV2);
- ADD_CODE(&td, *(td.ip + 1));
- td.ip += 2;
- td.sp -= 2;
- break;
- case CEE_MONO_PROC3:
- CHECK_STACK (&td, 3);
- ADD_CODE(&td, MINT_MONO_CONV3);
- ADD_CODE(&td, *(td.ip + 1));
- td.ip += 2;
- td.sp -= 3;
- break;
+ case CEE_MONO_ICALL: {
+ guint32 token;
+ gpointer func;
+ MonoJitICallInfo *info;
+
+ token = read32 (td.ip + 1);
+ td.ip += 5;
+ func = mono_method_get_wrapper_data (method, token);
+ info = mono_find_jit_icall_by_addr (func);
+ g_assert (info);
+
+ CHECK_STACK (&td, info->sig->param_count);
+ switch (info->sig->param_count) {
+ case 0:
+ if (MONO_TYPE_IS_VOID (info->sig->ret))
+ ADD_CODE (&td,MINT_ICALL_V_V);
+ else
+ g_assert_not_reached();
+ break;
+ case 1:
+ if (MONO_TYPE_IS_VOID (info->sig->ret))
+ ADD_CODE (&td,MINT_ICALL_P_V);
+ else
+ ADD_CODE (&td,MINT_ICALL_P_P);
+ break;
+ case 2:
+ if (MONO_TYPE_IS_VOID (info->sig->ret)) {
+ if (info->sig->params [1]->type == MONO_TYPE_I4)
+ ADD_CODE (&td,MINT_ICALL_PI_V);
+ else
+ ADD_CODE (&td,MINT_ICALL_PP_V);
+ } else {
+ if (info->sig->params [1]->type == MONO_TYPE_I4)
+ ADD_CODE (&td,MINT_ICALL_PI_P);
+ else
+ ADD_CODE (&td,MINT_ICALL_PP_P);
+ }
+ break;
+ case 3:
+ g_assert (MONO_TYPE_IS_VOID (info->sig->ret));
+ if (info->sig->params [2]->type == MONO_TYPE_I4)
+ ADD_CODE (&td,MINT_ICALL_PPI_V);
+ else
+ ADD_CODE (&td,MINT_ICALL_PPP_V);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ if (func == mono_ftnptr_to_delegate)
+ func = mono_interp_ftnptr_to_delegate;
+ ADD_CODE(&td, get_data_item_index (&td, func));
+ td.sp -= info->sig->param_count;
+
+ if (!MONO_TYPE_IS_VOID (info->sig->ret)) {
+ td.sp ++;
+ SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_I);
+ }
+ break;
+ }