INTERP_GET_EXCEPTION(arithmetic)
INTERP_GET_EXCEPTION_CHAR_ARG(argument_out_of_range)
+// Inlining throw logic into interp_exec_method makes it bigger and could push us up against
+// internal limits in things like WASM compilers
+static MONO_NEVER_INLINE void
+interp_throw_ex_general (
+ MonoException *__ex, ThreadContext *context, InterpFrame *frame, const guint16 *ex_ip, gboolean rethrow
+)
+{
+ HANDLE_FUNCTION_ENTER ();
+ MonoExceptionHandle tmp_handle = MONO_HANDLE_NEW (MonoException, __ex);
+ interp_throw (context, MONO_HANDLE_RAW(tmp_handle), (frame), (ex_ip), (rethrow));
+ HANDLE_FUNCTION_RETURN ();
+}
+
// We conservatively pin exception object here to avoid tweaking the
// numerous call sites of this macro, even though, in a few cases,
// this is not needed.
#define THROW_EX_GENERAL(exception,ex_ip, rethrow) \
do { \
- MonoException *__ex = (exception); \
- MONO_HANDLE_ASSIGN_RAW (tmp_handle, (MonoObject*)__ex); \
- interp_throw (context, __ex, (frame), (ex_ip), (rethrow)); \
- MONO_HANDLE_ASSIGN_RAW (tmp_handle, (MonoObject*)NULL); \
+ interp_throw_ex_general (exception, context, frame, ex_ip, rethrow); \
goto resume; \
} while (0)
#if USE_COMPUTED_GOTO
static void * const in_labels[] = {
#define OPDEF(a,b,c,d,e,f) &&LAB_ ## a,
+#define IROPDEF(a,b,c,d,e,f)
#include "mintops.def"
};
#endif
memset (locals + ip [1], 0, ip [2]);
ip += 3;
MINT_IN_BREAK;
- MINT_IN_CASE(MINT_NOP)
- MINT_IN_CASE(MINT_IL_SEQ_POINT)
- MINT_IN_CASE(MINT_NIY)
- MINT_IN_CASE(MINT_DEF)
- MINT_IN_CASE(MINT_DUMMY_USE)
- MINT_IN_CASE(MINT_TIER_PATCHPOINT_DATA)
-#ifndef HOST_BROWSER
- MINT_IN_CASE(MINT_TIER_NOP_JITERPRETER)
- MINT_IN_CASE(MINT_TIER_PREPARE_JITERPRETER)
- MINT_IN_CASE(MINT_TIER_ENTER_JITERPRETER)
-#endif
- g_assert_not_reached ();
- MINT_IN_BREAK;
MINT_IN_CASE(MINT_BREAK)
++ip;
SAVE_INTERP_STATE (frame);
ip += 3;
MINT_IN_BREAK;
- MINT_IN_CASE(MINT_MOV_SRC_OFF)
- MINT_IN_CASE(MINT_MOV_DST_OFF)
- // This opcode is resolved to a normal MINT_MOV when emitting compacted instructions
- g_assert_not_reached ();
- MINT_IN_BREAK;
-
#define MOV(argtype1,argtype2) \
LOCAL_VAR (ip [1], argtype1) = LOCAL_VAR (ip [2], argtype2); \
ip += 3;
#if !USE_COMPUTED_GOTO
default:
interp_error_xsx ("Unimplemented opcode: %04x %s at 0x%x\n", *ip, mono_interp_opname (*ip), GPTRDIFF_TO_INT (ip - frame->imethod->code));
-#endif
+#endif // USE_COMPUTED_GOTO
}
}
*
* OPDEF (opsymbol, opstring, oplength (in uint16s), num_dregs (0 or 1), num_sregs, optype)
* optype describes the contents of the instruction, following the dreg/sreg offsets.
- */
-
-/*
+ *
+ * IROPDEF is like OPDEF but for instructions that are never executed by the interpreter,
+ * meant for use by transform.c and other internals. They *must* be defined at the end after
+ * all regular OPDEFs.
+ *
* This file is parsed by genmintops.py to generate typescript during the wasm build process,
* so if you make any changes to its syntax you will need to update that script.
+ * Any preprocessing directives are removed without being parsed!
*/
-OPDEF(MINT_NOP, "nop", 1, 0, 0, MintOpNoArgs)
-OPDEF(MINT_NIY, "niy", 1, 0, 0, MintOpNoArgs)
-OPDEF(MINT_DEF, "def", 2, 1, 0, MintOpNoArgs)
-OPDEF(MINT_IL_SEQ_POINT, "il_seq_point", 1, 0, 0, MintOpNoArgs)
-OPDEF(MINT_DUMMY_USE, "dummy_use", 2, 0, 1, MintOpNoArgs)
-OPDEF(MINT_TIER_PATCHPOINT_DATA, "tier_patchpoint_data", 2, 0, 0, MintOpShortInt)
+#ifndef __MONO_CONFIG_H__
+#error You must include config.h before including mintops.def
+#endif
+
+// Compatibility shim for old code
+#ifndef IROPDEF
+#define __DEFINED_IROPDEF__
+#define IROPDEF(opsymbol, opstring, oplength, num_dregs, num_sregs, optype) OPDEF(opsymbol, opstring, oplength, num_dregs, num_sregs, optype)
+#endif // IROPDEF
+
OPDEF(MINT_BREAK, "break", 1, 0, 0, MintOpNoArgs)
OPDEF(MINT_BREAKPOINT, "breakpoint", 1, 0, 0, MintOpNoArgs)
OPDEF(MINT_LDSFLDA, "ldsflda", 4, 1, 0, MintOpTwoShorts)
OPDEF(MINT_LDTSFLDA, "ldtsflda", 4, 1, 0, MintOpInt)
-OPDEF(MINT_MOV_SRC_OFF, "mov.src.off", 6, 1, 1, MintOpTwoShorts)
-OPDEF(MINT_MOV_DST_OFF, "mov.dst.off", 6, 1, 1, MintOpTwoShorts)
-
OPDEF(MINT_MOV_I4_I1, "mov.i4.i1", 3, 1, 1, MintOpNoArgs)
OPDEF(MINT_MOV_I4_U1, "mov.i4.u1", 3, 1, 1, MintOpNoArgs)
OPDEF(MINT_MOV_I4_I2, "mov.i4.i2", 3, 1, 1, MintOpNoArgs)
OPDEF(MINT_METADATA_UPDATE_LDFLDA, "metadata_update.ldflda", 5, 1, 1, MintOpTwoShorts)
-// TODO: Make this wasm only
+// This ifdef is fine because genmintops.py is generating output for HOST_BROWSER
+#if HOST_BROWSER
OPDEF(MINT_TIER_PREPARE_JITERPRETER, "tier_prepare_jiterpreter", 3, 0, 0, MintOpInt)
OPDEF(MINT_TIER_NOP_JITERPRETER, "tier_nop_jiterpreter", 3, 0, 0, MintOpInt)
OPDEF(MINT_TIER_ENTER_JITERPRETER, "tier_enter_jiterpreter", 3, 0, 0, MintOpInt)
+#endif // HOST_BROWSER
+
+IROPDEF(MINT_NOP, "nop", 1, 0, 0, MintOpNoArgs)
+IROPDEF(MINT_NIY, "niy", 1, 0, 0, MintOpNoArgs)
+IROPDEF(MINT_DEF, "def", 2, 1, 0, MintOpNoArgs)
+IROPDEF(MINT_IL_SEQ_POINT, "il_seq_point", 1, 0, 0, MintOpNoArgs)
+IROPDEF(MINT_DUMMY_USE, "dummy_use", 2, 0, 1, MintOpNoArgs)
+IROPDEF(MINT_TIER_PATCHPOINT_DATA, "tier_patchpoint_data", 2, 0, 0, MintOpShortInt)
+// These two opcodes are resolved to a normal MINT_MOV when emitting compacted instructions
+IROPDEF(MINT_MOV_SRC_OFF, "mov.src.off", 6, 1, 1, MintOpTwoShorts)
+IROPDEF(MINT_MOV_DST_OFF, "mov.dst.off", 6, 1, 1, MintOpTwoShorts)
+
+#ifdef __DEFINED_IROPDEF__
+#undef IROPDEF
+#undef __DEFINED_IROPDEF__
+#endif // __DEFINED_IROPDEF__