{
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;
stack_size, n, (td)->ip - (td)->il_code); \
} while (0)
-#if SIZEOF_VOID_P == 4
-#define ENSURE_I4(td, sp_off)
-#else
#define ENSURE_I4(td, sp_off) \
do { \
if ((td)->sp [-sp_off].type == STACK_TYPE_I8) \
ADD_CODE(td, sp_off == 1 ? MINT_CONV_I4_I8 : MINT_CONV_I4_I8_SP); \
} while (0)
-#endif
static void
handle_branch(TransformData *td, int short_op, int long_op, int offset)
if (n == 0 && td->method->signature->hasthis)
ADD_CODE(td, MINT_STTHIS);
else {
+ MonoType *type;
n -= td->method->signature->hasthis;
- mt = mint_type (td->method->signature->params [n]);
- /* FIX value types */
- g_assert(mt != MINT_TYPE_VT);
- ADD_CODE(td, MINT_STARG_I1 + (mt - MINT_TYPE_I1));
- ADD_CODE(td, td->rtm->arg_offsets [n]);
+ type = td->method->signature->params [n];
+ mt = mint_type (type);
+ if (mt == MINT_TYPE_VT) {
+ gint32 size;
+ if (td->method->signature->pinvoke)
+ size = mono_class_native_size (type->data.klass, NULL);
+ else
+ size = mono_class_value_size (type->data.klass, NULL);
+ ADD_CODE(td, MINT_STARG_VT);
+ ADD_CODE(td, n);
+ WRITE32(td, &size);
+ if (td->sp [-1].type == STACK_TYPE_VT)
+ POP_VT(td, size);
+ } else {
+ ADD_CODE(td, MINT_STARG_I1 + (mt - MINT_TYPE_I1));
+ ADD_CODE(td, td->rtm->arg_offsets [n]);
+ }
}
--td->sp;
}
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);
}
if (mono_interp_traceopt) {
const guint16 *p = td.new_code;
printf("Runtime method: %p, VT stack size: %d\n", rtm, td.max_vt_sp);
- printf("Caculated stack size: %d, stated size: %d\n", td.max_stack_height, header->max_stack);
+ printf("Calculated stack size: %d, stated size: %d\n", td.max_stack_height, header->max_stack);
while (p < td.new_ip) {
p = mono_interp_dis_mintop(td.new_code, p);
printf("\n");
}
}
if (nm == NULL) {
+ runtime_method->stack_size = sizeof (stackval); /* for tracing */
+ runtime_method->alloca_size = runtime_method->stack_size;
runtime_method->transformed = TRUE;
LeaveCriticalSection(&calc_section);
mono_profiler_method_end_jit (method, MONO_PROFILE_OK);
}
else if (in == 0xf0) {
ip++;
- in = *ip + MONO_CEE_MONO_FUNC1;
+ in = *ip + MONO_CEE_MONO_ICALL;
}
opcode = &mono_opcodes [in];
switch (opcode->argument) {