2009-12-13 Zoltan Varga <vargaz@gmail.com>
+ * mini-ops.h (OP_IMPLICIT_EXCEPTION): New opcode marking the place where an
+ implicit exception can occur.
+
+ * ir-emit.h (MONO_EMIT_NEW_IMPLICIT_EXCEPTION): New macro to emit an
+ OP_IMPLICIT_EXCEPTION instruction.
+
+ * ir-emit.h (MONO_EMIT_NEW_CHECK_THIS): New macro.
+
+ * method-to-ir.c: Use MONO_EMIT_NEW_CHECK_THIS in a few places.
+
+ * mini-llvm.c: Handle OP_IMPLICIT_EXCEPTION by disabling llvm if it occurs
+ inside a protected block.
+
* mini-llvm.c: Revert the last change, the signature of monitor entry/exit
trampolines doesn't include the argument.
(cfg)->cbb = (bblock); \
} while (0)
+/* This marks a place in code where an implicit exception could be thrown */
+#define MONO_EMIT_NEW_IMPLICIT_EXCEPTION(cfg) do { \
+ if (COMPILE_LLVM ((cfg))) { \
+ MONO_EMIT_NEW_UNALU (cfg, OP_IMPLICIT_EXCEPTION, -1, -1); \
+ } \
+ } while (0)
+
+#define MONO_EMIT_NEW_CHECK_THIS(cfg, sreg) do { \
+ cfg->flags |= MONO_CFG_HAS_CHECK_THIS; \
+ MONO_EMIT_NEW_IMPLICIT_EXCEPTION (cfg); \
+ MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, sreg); \
+ MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, sreg); \
+ } while (0)
+
/*Object Model related macros*/
#ifndef MONO_ARCH_EMIT_BOUNDS_CHECK
MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, (reg), 0); \
MONO_EMIT_NEW_COND_EXC (cfg, EQ, "NullReferenceException"); \
} \
+ MONO_EMIT_NEW_IMPLICIT_EXCEPTION (cfg); \
} while (0)
/* cfg is the MonoCompile been used
method = call->method = mono_marshal_get_remoting_invoke_with_check (method);
}
- if (!method->string_ctor) {
- cfg->flags |= MONO_CFG_HAS_CHECK_THIS;
- MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, this_reg);
- MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, this_reg);
- }
+ if (!method->string_ctor)
+ MONO_EMIT_NEW_CHECK_THIS (cfg, this_reg);
call->inst.opcode = callvirt_to_call (call->inst.opcode);
* it's class or the method itself are sealed.
* But first we need to ensure it's not a null reference.
*/
- cfg->flags |= MONO_CFG_HAS_CHECK_THIS;
- MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, this_reg);
- MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, this_reg);
+ MONO_EMIT_NEW_CHECK_THIS (cfg, this_reg);
call->inst.opcode = callvirt_to_call (call->inst.opcode);
MONO_ADD_INS (cfg->cbb, (MonoInst*)call);
NEW_ARGLOAD (cfg, arg_ins, 0);
MONO_ADD_INS (cfg->cbb, arg_ins);
- cfg->flags |= MONO_CFG_HAS_CHECK_THIS;
- MONO_EMIT_NEW_UNALU (cfg, OP_CHECK_THIS, -1, arg_ins->dreg);
- MONO_EMIT_NEW_UNALU (cfg, OP_NOT_NULL, -1, arg_ins->dreg);
+ MONO_EMIT_NEW_CHECK_THIS (cfg, arg_ins->dreg);
}
/* we use a spare stack slot in SWITCH and NEWOBJ and others */
cmethod, MONO_RGCTX_INFO_METHOD);
}
- if (check_this) {
- MonoInst *check;
-
- MONO_INST_NEW (cfg, check, OP_CHECK_THIS);
- check->sreg1 = sp [0]->dreg;
- MONO_ADD_INS (cfg->cbb, check);
- }
+ if (check_this)
+ MONO_EMIT_NEW_CHECK_THIS (cfg, sp [0]->dreg);
/* Calling virtual generic methods */
if (cmethod && virtual &&
}
}
+ if (cfg->vret_addr)
+ emit_volatile_store (ctx, cfg->vret_addr->dreg);
if (sig->hasthis)
emit_volatile_store (ctx, cfg->args [0]->dreg);
for (i = 0; i < sig->param_count; ++i)
/*
* EXCEPTION HANDLING
*/
+ case OP_IMPLICIT_EXCEPTION:
+ /* This marks a place where an implicit exception can happen */
+ if (bb->region != -1)
+ LLVM_FAILURE (ctx, "implicit-exception");
+ break;
case OP_THROW: {
MonoMethodSignature *throw_sig;
LLVMValueRef callee, arg;
MINI_OP(OP_LOCALLOC_IMM, "localloc_imm", IREG, NONE, NONE)
MINI_OP(OP_CHECK_THIS, "checkthis", NONE, IREG, NONE)
MINI_OP(OP_SEQ_POINT, "seq_point", NONE, NONE, NONE)
+MINI_OP(OP_IMPLICIT_EXCEPTION, "implicit_exception", NONE, NONE, NONE)
MINI_OP(OP_VOIDCALL, "voidcall", NONE, NONE, NONE)
MINI_OP(OP_VOIDCALLVIRT, "voidcallvirt", NONE, NONE, NONE)