#include <pthread.h>
#endif
+#ifdef PLATFORM_WIN32
+#define _WIN32_WINNT 0x0500
+#endif
+
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#endif
ins->type = STACK_PTR;
switch (ins->inst_i0->type) {
case STACK_I4:
+ break;
case STACK_PTR:
case STACK_MP:
+#if SIZEOF_VOID_P == 8
+ ins->opcode = OP_LCONV_TO_U;
+#endif
break;
case STACK_I8:
ins->opcode = OP_LCONV_TO_U;
MONO_INIT_VARINFO (cfg->vars [num], num);
cfg->num_varinfo++;
- //g_print ("created temp %d of type %s\n", num, mono_type_get_name (type));
+ if (cfg->verbose_level > 2)
+ g_print ("created temp %d of type %s\n", num, mono_type_get_name (type));
return inst;
}
return &ins->klass->this_arg;
else
return &mono_defaults.object_class->this_arg;
- case STACK_OBJ: return &mono_defaults.object_class->byval_arg;
+ case STACK_OBJ:
+ /* ins->klass may not be set for ldnull.
+ * Also, if we have a boxed valuetype, we want an object lass,
+ * not the valuetype class
+ */
+ if (ins->klass && !ins->klass->valuetype)
+ return &ins->klass->byval_arg;
+ return &mono_defaults.object_class->byval_arg;
case STACK_VTYPE: return &ins->klass->byval_arg;
default:
g_error ("stack type %d to montype not handled\n", ins->type);
}
static MonoClass*
-array_access_to_klass (int opcode)
+array_access_to_klass (int opcode, MonoInst *array_obj)
{
switch (opcode) {
case CEE_LDELEM_U1:
case CEE_STELEM_R8:
return mono_defaults.double_class;
case CEE_LDELEM_REF:
- case CEE_STELEM_REF:
+ case CEE_STELEM_REF: {
+ MonoClass *klass = array_obj->klass;
+ /* FIXME: add assert */
+ if (klass && klass->rank)
+ return klass->element_class;
return mono_defaults.object_class;
+ }
default:
g_assert_not_reached ();
}
* in the inlined methods do not inherit their in_stack from
* the bblock they are inlined to. See bug #58863 for an
* example.
+ * This hack is disabled since it also prevents proper tracking of types.
*/
+#if 1
+ bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
+#else
if (cfg->inlined_method)
bb->out_stack [i] = mono_compile_create_var (cfg, type_from_stack_type (sp [i]), OP_LOCAL);
else
bb->out_stack [i] = mono_compile_get_interface_var (cfg, i, sp [i]);
+#endif
}
}
}
if (arg->type != STACK_I4 && arg->type != STACK_PTR)
return 1;
return 0;
- case MONO_TYPE_CLASS:
- case MONO_TYPE_STRING:
case MONO_TYPE_OBJECT:
+ if (arg->type != STACK_OBJ)
+ return 1;
+ return 0;
+ case MONO_TYPE_STRING:
+ if (arg->type != STACK_OBJ)
+ return 1;
+ /* ldnull has arg->klass unset */
+ /*if (arg->klass && arg->klass != mono_defaults.string_class) {
+ G_BREAKPOINT ();
+ return 1;
+ }*/
+ return 0;
+ case MONO_TYPE_CLASS:
case MONO_TYPE_SZARRAY:
case MONO_TYPE_ARRAY:
if (arg->type != STACK_OBJ)
MONO_INST_NEW (cfg, ins, CEE_BREAK);
return ins;
}
+ if (cmethod->name [0] == 'g' && strcmp (cmethod->name, "get_IsRunningOnWindows") == 0
+ && strcmp (cmethod->klass->name, "Environment") == 0) {
+#ifdef PLATFORM_WIN32
+ NEW_ICONST (cfg, ins, 1);
+#else
+ NEW_ICONST (cfg, ins, 0);
+#endif
+ return ins;
+ }
}
return mono_arch_get_inst_for_method (cfg, cmethod, fsig, args);
static gboolean
can_access_member (MonoClass *access_klass, MonoClass *member_klass, int access_level)
{
+ if (access_klass->generic_class && member_klass->generic_class &&
+ access_klass->generic_class->container_class && member_klass->generic_class->container_class) {
+ if (can_access_member (access_klass->generic_class->container_class,
+ member_klass->generic_class->container_class, access_level))
+ return TRUE;
+ }
+
/* Partition I 8.5.3.2 */
/* the access level values are the same for fields and methods */
switch (access_level) {
/* same compilation unit */
return access_klass->image == member_klass->image;
case FIELD_ATTRIBUTE_PRIVATE:
- if (access_klass->generic_class && member_klass->generic_class && member_klass->generic_class->container_class)
- return member_klass->generic_class->container_class == access_klass->generic_class->container_class;
return access_klass == member_klass;
case FIELD_ATTRIBUTE_FAM_AND_ASSEM:
if (mono_class_has_parent (access_klass, member_klass) &&
- can_access_internals (access_klass->image->assembly, member_klass->image->assembly))
+ can_access_internals (access_klass->image->assembly, member_klass->image->assembly))
return TRUE;
return FALSE;
case FIELD_ATTRIBUTE_ASSEMBLY:
} else if (constrained_call) {
cmethod = mono_get_method_constrained (image, token, constrained_call, generic_context, &cil_method);
cmethod = mono_get_inflated_method (cmethod);
+ cil_method = cmethod;
} else {
cmethod = mini_get_method (method, token, NULL, generic_context);
cil_method = cmethod;
n = read32 (ip + 1);
if (method->wrapper_type == MONO_WRAPPER_DYNAMIC_METHOD) {
+ /* FIXME: moving GC */
NEW_PCONST (cfg, ins, mono_method_get_wrapper_data (method, n));
ins->cil_code = ip;
ins->type = STACK_OBJ;
link_bblock (cfg, bblock, tblock);
CHECK_BBLOCK (target, ip, tblock);
ins->inst_target_bb = tblock;
+ GET_BBLOCK (cfg, bbhash, tblock, ip);
+ link_bblock (cfg, bblock, tblock);
if (sp != stack_start) {
handle_stack_args (cfg, bblock, stack_start, sp - stack_start);
sp = stack_start;
ins->inst_newa_class = klass;
ins->inst_newa_len = *sp;
ins->type = STACK_OBJ;
- ins->klass = klass;
+ ins->klass = mono_array_class_get (klass, 1);
ip += 5;
*sp++ = ins;
/*
sp -= 2;
if (sp [0]->type != STACK_OBJ)
UNVERIFIED;
- klass = array_access_to_klass (*ip);
+ klass = array_access_to_klass (*ip, sp [0]);
NEW_LDELEMA (cfg, load, sp, klass);
load->cil_code = ip;
#ifdef MONO_ARCH_SOFT_FLOAT
sp -= 3;
if (sp [0]->type != STACK_OBJ)
UNVERIFIED;
- klass = array_access_to_klass (*ip);
+ klass = array_access_to_klass (*ip, sp [0]);
NEW_LDELEMA (cfg, load, sp, klass);
load->cil_code = ip;
#ifdef MONO_ARCH_SOFT_FLOAT
g_list_free (regs);
}
+ /* todo: remove code when we have verified that the liveness for try/catch blocks
+ * works perfectly
+ */
+ /*
+ * Currently, this can't be commented out since exception blocks are not
+ * processed during liveness analysis.
+ */
+ mono_liveness_handle_exception_clauses (cfg);
+
if (cfg->opt & MONO_OPT_LINEARS) {
GList *vars, *regs;
mono_arch_handle_exception (ctx, exc, FALSE);
}
+#ifndef PLATFORM_WIN32
+
static void
SIG_HANDLER_SIGNATURE (sigabrt_signal_handler)
{
mono_print_thread_dump (ctx);
}
+static void
+SIG_HANDLER_SIGNATURE (sigusr2_signal_handler)
+{
+ gboolean enabled = mono_trace_is_enabled ();
+
+ mono_trace_enable (!enabled);
+}
+
+#endif
+
static void
SIG_HANDLER_SIGNATURE (sigint_signal_handler)
{
mono_arch_handle_exception (ctx, exc, FALSE);
}
-static void
-SIG_HANDLER_SIGNATURE (sigusr2_signal_handler)
-{
- gboolean enabled = mono_trace_is_enabled ();
-
- mono_trace_enable (!enabled);
-}
-
#ifdef PLATFORM_MACOSX
/*
}
#endif
+#ifdef PLATFORM_WIN32
+static HANDLE win32_main_thread;
+static MMRESULT win32_timer;
+
+static void CALLBACK
+win32_time_proc (UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
+{
+ CONTEXT context;
+
+ context.ContextFlags = CONTEXT_CONTROL;
+ if (GetThreadContext (win32_main_thread, &context)) {
+#ifdef _WIN64
+ mono_profiler_stat_hit ((guchar *) context.Rip, &context);
+#else
+ mono_profiler_stat_hit ((guchar *) context.Eip, &context);
+#endif
+ }
+}
+#endif
+
static void
setup_stat_profiler (void)
{
return;
inited = 1;
add_signal_handler (SIGPROF, sigprof_signal_handler);
+#elif defined (PLATFORM_WIN32)
+ static int inited = 0;
+ TIMECAPS timecaps;
+
+ if (inited)
+ return;
+
+ inited = 1;
+ if (timeGetDevCaps (&timecaps, sizeof (timecaps)) != TIMERR_NOERROR)
+ return;
+
+ if ((win32_main_thread = OpenThread (READ_CONTROL | THREAD_GET_CONTEXT, FALSE, GetCurrentThreadId ())) == NULL)
+ return;
+
+ if (timeBeginPeriod (1) != TIMERR_NOERROR)
+ return;
+
+ if ((win32_timer = timeSetEvent (1, 0, win32_time_proc, 0, TIME_PERIODIC)) == 0) {
+ timeEndPeriod (1);
+ return;
+ }
#endif
}