}
static void inline
-stackval_from_data (MonoType *type, stackval *result, char *data, gboolean pinvoke)
+stackval_from_data (MonoType *type_, stackval *result, char *data, gboolean pinvoke)
{
+ MonoType *type = mini_native_type_replace_type (type_);
if (type->byref) {
switch (type->type) {
case MONO_TYPE_OBJECT:
}
static void inline
-stackval_to_data (MonoType *type, stackval *val, char *data, gboolean pinvoke)
+stackval_to_data (MonoType *type_, stackval *val, char *data, gboolean pinvoke)
{
+ MonoType *type = mini_native_type_replace_type (type_);
if (type->byref) {
gpointer *p = (gpointer*)data;
*p = val->data.p;
int i8_align = mono_arm_i8_align ();
#endif
+#ifdef TARGET_WASM
+ margs->sig = sig;
+#endif
+
if (sig->hasthis)
margs->ilen++;
MINT_IN_CASE(MINT_NOP)
++ip;
MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_NIY)
+ g_error ("mint_niy: instruction not implemented yet. This shouldn't happen.");
+ MINT_IN_BREAK;
MINT_IN_CASE(MINT_BREAK)
++ip;
do_debugger_tramp (mono_debugger_agent_user_break, frame);
}
MINT_IN_CASE(MINT_JMP) {
InterpMethod *new_method = rtm->data_items [* (guint16 *)(ip + 1)];
+
+ if (frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_TAIL_CALL)
+ MONO_PROFILER_RAISE (method_tail_call, (frame->imethod->method, new_method->method));
+
if (!new_method->transformed) {
frame->ip = ip;
frame->ex = mono_interp_transform_method (new_method, context);
++sp;
MINT_IN_BREAK;
}
+ MINT_IN_CASE(MINT_NEWOBJ_MAGIC) {
+ guint32 token;
+
+ frame->ip = ip;
+ token = * (guint16 *)(ip + 1);
+ ip += 2;
+
+ MINT_IN_BREAK;
+ }
MINT_IN_CASE(MINT_CASTCLASS)
c = rtm->data_items [*(guint16 *)(ip + 1)];
if ((o = sp [-1].data.p)) {
c = rtm->data_items [* (guint16 *)(ip + 1)];
guint16 offset = * (guint16 *)(ip + 2);
- if (c->byval_arg.type == MONO_TYPE_VALUETYPE && !c->enumtype) {
+ if (c->byval_arg.type == MONO_TYPE_VALUETYPE && !c->enumtype && !(mono_class_is_magic_int (c) || mono_class_is_magic_float (c))) {
int size = mono_class_value_size (c, NULL);
sp [-1 - offset].data.p = mono_value_box_checked (rtm->domain, c, sp [-1 - offset].data.p, &error);
mono_error_cleanup (&error); /* FIXME: don't swallow the error */
--sp; \
sp [-1].data.i = sp [-1].data.datamem op sp [0].data.datamem; \
++ip;
+
+#define RELOP_FP(datamem, op, noorder) \
+ --sp; \
+ if (isunordered (sp [-1].data.datamem, sp [0].data.datamem)) \
+ sp [-1].data.i = noorder; \
+ else \
+ sp [-1].data.i = sp [-1].data.datamem op sp [0].data.datamem; \
+ ++ip;
+
MINT_IN_CASE(MINT_CEQ_I4)
RELOP(i, ==);
MINT_IN_BREAK;
RELOP(l, ==);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CEQ_R8)
- --sp;
- if (isunordered (sp [-1].data.f, sp [0].data.f))
- sp [-1].data.i = 0;
- else
- sp [-1].data.i = sp [-1].data.f == sp [0].data.f;
- ++ip;
+ RELOP_FP(f, ==, 0);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CNE_I4)
+ RELOP(i, !=);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CNE_I8)
+ RELOP(l, !=);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CNE_R8)
+ RELOP_FP(f, !=, 0);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CGT_I4)
RELOP(i, >);
RELOP(l, >);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CGT_R8)
- --sp;
- if (isunordered (sp [-1].data.f, sp [0].data.f))
- sp [-1].data.i = 0;
- else
- sp [-1].data.i = sp [-1].data.f > sp [0].data.f;
- ++ip;
+ RELOP_FP(f, >, 0);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CGE_I4)
+ RELOP(i, >=);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CGE_I8)
+ RELOP(l, >=);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CGE_R8)
+ RELOP_FP(f, >=, 0);
MINT_IN_BREAK;
#define RELOP_CAST(datamem, op, type) \
sp [-1].data.i = (type)sp [-1].data.datamem op (type)sp [0].data.datamem; \
++ip;
+ MINT_IN_CASE(MINT_CGE_UN_I4)
+ RELOP_CAST(l, >=, guint32);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CGE_UN_I8)
+ RELOP_CAST(l, >=, guint64);
+ MINT_IN_BREAK;
+
MINT_IN_CASE(MINT_CGT_UN_I4)
RELOP_CAST(i, >, guint32);
MINT_IN_BREAK;
RELOP_CAST(l, >, guint64);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CGT_UN_R8)
- --sp;
- if (isunordered (sp [-1].data.f, sp [0].data.f))
- sp [-1].data.i = 1;
- else
- sp [-1].data.i = sp [-1].data.f > sp [0].data.f;
- ++ip;
+ RELOP_FP(f, >, 1);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CLT_I4)
RELOP(i, <);
RELOP(l, <);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CLT_R8)
- --sp;
- if (isunordered (sp [-1].data.f, sp [0].data.f))
- sp [-1].data.i = 0;
- else
- sp [-1].data.i = sp [-1].data.f < sp [0].data.f;
- ++ip;
+ RELOP_FP(f, <, 0);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CLT_UN_I4)
RELOP_CAST(i, <, guint32);
RELOP_CAST(l, <, guint64);
MINT_IN_BREAK;
MINT_IN_CASE(MINT_CLT_UN_R8)
- --sp;
- if (isunordered (sp [-1].data.f, sp [0].data.f))
- sp [-1].data.i = 1;
- else
- sp [-1].data.i = sp [-1].data.f < sp [0].data.f;
- ++ip;
+ RELOP_FP(f, <, 1);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CLE_I4)
+ RELOP(i, <=);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CLE_I8)
+ RELOP(l, <=);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CLE_UN_I4)
+ RELOP_CAST(l, <=, guint32);
+ MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CLE_UN_I8)
+ RELOP_CAST(l, <=, guint64);
MINT_IN_BREAK;
+ MINT_IN_CASE(MINT_CLE_R8)
+ RELOP_FP(f, <=, 0);
+ MINT_IN_BREAK;
+
+#undef RELOP
+#undef RELOP_FP
+#undef RELOP_CAST
+
MINT_IN_CASE(MINT_LDFTN) {
sp->data.p = rtm->data_items [* (guint16 *)(ip + 1)];
++sp;
if (MONO_PROFILER_ENABLED (method_enter)) {
MonoProfilerCallContext *prof_ctx = NULL;
- if (frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_PROLOGUE_CONTEXT) {
+ if (frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_ENTER_CONTEXT) {
prof_ctx = g_new0 (MonoProfilerCallContext, 1);
prof_ctx->interp_frame = frame;
prof_ctx->method = frame->imethod->method;
}
exit_frame:
- if (!frame->ex) {
- if (MONO_PROFILER_ENABLED (method_leave) && frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE) {
- MonoProfilerCallContext *prof_ctx = NULL;
-
- if (frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_EPILOGUE_CONTEXT) {
- prof_ctx = g_new0 (MonoProfilerCallContext, 1);
- prof_ctx->interp_frame = frame;
- prof_ctx->method = frame->imethod->method;
-
- MonoType *rtype = mono_method_signature (frame->imethod->method)->ret;
-
- switch (rtype->type) {
- case MONO_TYPE_VOID:
- break;
- case MONO_TYPE_VALUETYPE:
- prof_ctx->return_value = frame->retval->data.p;
- break;
- default:
- prof_ctx->return_value = frame->retval;
- break;
- }
- }
+ if (!frame->ex && MONO_PROFILER_ENABLED (method_leave) &&
+ frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_LEAVE) {
+ MonoProfilerCallContext *prof_ctx = NULL;
+
+ if (frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_LEAVE_CONTEXT) {
+ prof_ctx = g_new0 (MonoProfilerCallContext, 1);
+ prof_ctx->interp_frame = frame;
+ prof_ctx->method = frame->imethod->method;
- MONO_PROFILER_RAISE (method_leave, (frame->imethod->method, prof_ctx));
+ MonoType *rtype = mono_method_signature (frame->imethod->method)->ret;
- g_free (prof_ctx);
+ switch (rtype->type) {
+ case MONO_TYPE_VOID:
+ break;
+ case MONO_TYPE_VALUETYPE:
+ prof_ctx->return_value = frame->retval->data.p;
+ break;
+ default:
+ prof_ctx->return_value = frame->retval;
+ break;
+ }
}
- } else
- MONO_PROFILER_RAISE (method_exception_leave, (frame->imethod->method, (MonoObject *) frame->ex));
+
+ MONO_PROFILER_RAISE (method_leave, (frame->imethod->method, prof_ctx));
+
+ g_free (prof_ctx);
+ } else if (frame->ex && frame->imethod->prof_flags & MONO_PROFILER_CALL_INSTRUMENTATION_EXCEPTION_LEAVE)
+ MONO_PROFILER_RAISE (method_exception_leave, (frame->imethod->method, &frame->ex->object));
DEBUG_LEAVE ();
}