}
} else {
int j;
+ int may_throw = 0;
if (!zend_jit_return(&dasm_state, opline, op_array,
op1_info, OP1_REG_ADDR())) {
if (!zend_jit_free_cv(&dasm_state, opline, op_array, info, j)) {
goto jit_failure;
}
+ if (info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_RESOURCE)) {
+ if (info & MAY_BE_RC1) {
+ may_throw = 1;
+ }
+ }
}
}
- if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM])) {
+ if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM], may_throw)) {
goto jit_failure;
}
}
return 1;
}
-static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info)
+static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, zend_jit_trace_rec *trace, zend_jit_trace_info *trace_info, int may_throw)
{
/* ZEND_CALL_FAKE_CLOSURE handled on slow path to eliminate check for ZEND_CALL_CLOSURE on fast path */
| mov FCARG1d, dword [FP + offsetof(zend_execute_data, This.u1.type_info)]
&& (JIT_G(current_frame) && !TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {
zend_jit_reset_opline(Dst, NULL);
} else {
- // TODO: exception handling for tracing JIT ???
| LOAD_OPLINE
| ADD_IP sizeof(zend_op)
}
|8:
+ if ((trace->op != ZEND_JIT_TRACE_END ||
+ trace->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) &&
+ may_throw) {
+ | // if (EG(exception))
+ | MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
+ | jne ->leave_throw_handler
+ }
+
if (trace->op == ZEND_JIT_TRACE_BACK
&& (!JIT_G(current_frame) || TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {
const zend_op *next_opline = trace->opline;
} while (trace->op == ZEND_JIT_TRACE_INIT_CALL);
ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END);
next_opline = trace->opline;
+ ZEND_ASSERT(next_opline != NULL);
current_frame = JIT_G(current_frame);
JIT_G(current_frame) = NULL;
exit_point = zend_jit_trace_get_exit_point(opline, NULL, trace, 0);
if (!exit_addr) {
return 0;
}
- | // TODO: exception handling ???
if (trace->op == ZEND_JIT_TRACE_END
&& trace->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {
trace_info->flags |= ZEND_JIT_TRACE_LOOP;