Skip to content

Commit 2a72778

Browse files
committed
Check for EG(exception) after leaving function frame
1 parent 251e667 commit 2a72778

File tree

3 files changed

+18
-5
lines changed

3 files changed

+18
-5
lines changed

ext/opcache/jit/zend_jit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2727,7 +2727,7 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
27272727
}
27282728
}
27292729
}
2730-
if (!zend_jit_leave_func(&dasm_state, opline, op_array, NULL, NULL)) {
2730+
if (!zend_jit_leave_func(&dasm_state, opline, op_array, NULL, NULL, 1)) {
27312731
goto jit_failure;
27322732
}
27332733
}

ext/opcache/jit/zend_jit_trace.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3724,6 +3724,7 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
37243724
}
37253725
} else {
37263726
int j;
3727+
int may_throw = 0;
37273728

37283729
if (!zend_jit_return(&dasm_state, opline, op_array,
37293730
op1_info, OP1_REG_ADDR())) {
@@ -3750,9 +3751,14 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
37503751
if (!zend_jit_free_cv(&dasm_state, opline, op_array, info, j)) {
37513752
goto jit_failure;
37523753
}
3754+
if (info & (MAY_BE_OBJECT|MAY_BE_RESOURCE|MAY_BE_ARRAY_OF_OBJECT|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_ARRAY_OF_RESOURCE)) {
3755+
if (info & MAY_BE_RC1) {
3756+
may_throw = 1;
3757+
}
3758+
}
37533759
}
37543760
}
3755-
if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM])) {
3761+
if (!zend_jit_leave_func(&dasm_state, opline, op_array, p + 1, &zend_jit_traces[ZEND_JIT_TRACE_NUM], may_throw)) {
37563762
goto jit_failure;
37573763
}
37583764
}

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9986,7 +9986,7 @@ static int zend_jit_free_op(dasm_State **Dst, const zend_op *opline, /*const zen
99869986
return 1;
99879987
}
99889988

9989-
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)
9989+
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)
99909990
{
99919991
/* ZEND_CALL_FAKE_CLOSURE handled on slow path to eliminate check for ZEND_CALL_CLOSURE on fast path */
99929992
| mov FCARG1d, dword [FP + offsetof(zend_execute_data, This.u1.type_info)]
@@ -10055,13 +10055,20 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
1005510055
&& (JIT_G(current_frame) && !TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {
1005610056
zend_jit_reset_opline(Dst, NULL);
1005710057
} else {
10058-
// TODO: exception handling for tracing JIT ???
1005910058
| LOAD_OPLINE
1006010059
| ADD_IP sizeof(zend_op)
1006110060
}
1006210061

1006310062
|8:
1006410063

10064+
if ((trace->op != ZEND_JIT_TRACE_END ||
10065+
trace->stop != ZEND_JIT_TRACE_STOP_RECURSIVE_RET) &&
10066+
may_throw) {
10067+
| // if (EG(exception))
10068+
| MEM_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
10069+
| jne ->leave_throw_handler
10070+
}
10071+
1006510072
if (trace->op == ZEND_JIT_TRACE_BACK
1006610073
&& (!JIT_G(current_frame) || TRACE_FRAME_IS_UNKNOWN_RETURN(JIT_G(current_frame)))) {
1006710074
const zend_op *next_opline = trace->opline;
@@ -10074,6 +10081,7 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
1007410081
} while (trace->op == ZEND_JIT_TRACE_INIT_CALL);
1007510082
ZEND_ASSERT(trace->op == ZEND_JIT_TRACE_VM || trace->op == ZEND_JIT_TRACE_END);
1007610083
next_opline = trace->opline;
10084+
ZEND_ASSERT(next_opline != NULL);
1007710085
current_frame = JIT_G(current_frame);
1007810086
JIT_G(current_frame) = NULL;
1007910087
exit_point = zend_jit_trace_get_exit_point(opline, NULL, trace, 0);
@@ -10082,7 +10090,6 @@ static int zend_jit_leave_func(dasm_State **Dst, const zend_op *opline, const ze
1008210090
if (!exit_addr) {
1008310091
return 0;
1008410092
}
10085-
| // TODO: exception handling ???
1008610093
if (trace->op == ZEND_JIT_TRACE_END
1008710094
&& trace->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET) {
1008810095
trace_info->flags |= ZEND_JIT_TRACE_LOOP;

0 commit comments

Comments
 (0)