{
unsigned int old_ip_offset = td->new_ip - td->new_code;
unsigned int old_last_ip_offset = td->last_new_ip - td->new_code;
+ g_assert (old_ip_offset <= td->max_code_size);
td->new_code = g_realloc (td->new_code, (td->max_code_size *= 2) * sizeof (td->new_code [0]));
td->new_code_end = td->new_code + td->max_code_size;
td->new_ip = td->new_code + old_ip_offset;
case CEE_DUP: {
int type = td.sp [-1].type;
MonoClass *klass = td.sp [-1].klass;
- if (td.sp [-1].type == STACK_TYPE_VT)
- g_warning ("dup of value type not implemented");
- SIMPLE_OP(td, MINT_DUP);
+ if (td.sp [-1].type == STACK_TYPE_VT) {
+ gint32 size = mono_class_value_size (klass, NULL);
+ PUSH_VT(&td, size);
+ ADD_CODE(&td, MINT_DUP_VT);
+ WRITE32(&td, &size);
+ td.ip ++;
+ } else
+ SIMPLE_OP(td, MINT_DUP);
PUSH_TYPE(&td, type, klass);
break;
}
CHECK_STACK (&td, 1);
token = read32 (td.ip + 1);
klass = mono_class_get_full (image, token, generic_context);
- *td.new_ip ++ = MINT_CASTCLASS;
+ ADD_CODE(&td, MINT_CASTCLASS);
ADD_CODE(&td, get_data_item_index (&td, klass));
+ td.sp [-1].klass = klass;
td.ip += 5;
break;
case CEE_ISINST:
CHECK_STACK (&td, 1);
token = read32 (td.ip + 1);
klass = mono_class_get_full (image, token, generic_context);
- *td.new_ip ++ = MINT_ISINST;
+ ADD_CODE(&td, MINT_ISINST);
ADD_CODE(&td, get_data_item_index (&td, klass));
td.ip += 5;
break;
else
klass = mono_class_get_full (image, token, generic_context);
- *td.new_ip ++ = MINT_UNBOX;
+ ADD_CODE(&td, MINT_UNBOX);
ADD_CODE(&td, get_data_item_index (&td, klass));
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP);
td.ip += 5;
case CEE_UNUSED41:
++td.ip;
switch (*td.ip) {
- 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 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))
+ ADD_CODE (&td,MINT_ICALL_PP_V);
+ else
+ ADD_CODE (&td,MINT_ICALL_PP_P);
+ break;
+ case 3:
+ g_assert (MONO_TYPE_IS_VOID (info->sig->ret));
+ ADD_CODE (&td,MINT_ICALL_PPP_V);
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ 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;
+ }
case CEE_MONO_VTADDR: {
int size;
CHECK_STACK (&td, 1);
td.sp [0].type = STACK_TYPE_I;
++td.sp;
break;
- case CEE_MONO_FREE:
- CHECK_STACK (&td, 1);
- ADD_CODE(&td, MINT_MONO_FREE);
- ++td.ip;
- --td.sp;
- break;
case CEE_MONO_OBJADDR:
CHECK_STACK (&td, 1);
++td.ip;
g_assert(klass->valuetype);
SET_SIMPLE_TYPE(td.sp - 1, STACK_TYPE_MP);
break;
+ case CEE_MONO_SAVE_LMF:
+ case CEE_MONO_RESTORE_LMF:
+ ++td.ip;
+ break;
default:
g_error ("transform.c: Unimplemented opcode: 0xF0 %02x at 0x%x\n", *td.ip, td.ip-header->code);
}
}
else if (in == 0xf0) {
ip++;
- in = *ip + MONO_CEE_MONO_FUNC1;
+ in = *ip + MONO_CEE_MONO_ICALL;
}
opcode = &mono_opcodes [in];
switch (opcode->argument) {