@@ -8653,24 +8653,47 @@ static int zend_jit_push_call_frame(zend_jit_ctx *jit, const zend_op *opline, co
8653
8653
return 1;
8654
8654
}
8655
8655
8656
+ static int zend_jit_func_guard(zend_jit_ctx *jit, ir_ref func_ref, const zend_function *func, const void *exit_addr)
8657
+ {
8658
+ if (func->type == ZEND_USER_FUNCTION &&
8659
+ (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
8660
+ (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
8661
+ !func->common.function_name)) {
8662
+ const zend_op *opcodes = func->op_array.opcodes;
8663
+
8664
+ // JIT: if (call->func.op_array.opcodes != opcodes) goto exit_addr;
8665
+ ir_GUARD(
8666
+ ir_EQ(
8667
+ ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
8668
+ ir_CONST_ADDR(opcodes)),
8669
+ ir_CONST_ADDR(exit_addr));
8670
+ #ifdef ZEND_WIN32
8671
+ } else if (func->type == ZEND_INTERNAL_FUNCTION) {
8672
+ // ASLR may cause different addresses in different workers. Check for the internal function handler.
8673
+ // JIT: if (call->func.internal_function.handler != handler) goto exit_addr;
8674
+ ir_GUARD(
8675
+ ir_EQ(
8676
+ ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_internal_function, handler))),
8677
+ ir_CONST_FC_FUNC(func->internal_function.handler)),
8678
+ ir_CONST_ADDR(exit_addr));
8679
+ #endif
8680
+ } else {
8681
+ // JIT: if (call->func != func) goto exit_addr;
8682
+ ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8683
+ }
8684
+
8685
+ return 1;
8686
+ }
8687
+
8656
8688
static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const zend_function *func, const zend_op *to_opline)
8657
8689
{
8658
8690
int32_t exit_point;
8659
8691
const void *exit_addr;
8660
8692
ir_ref call;
8661
8693
8662
- if (func->type == ZEND_INTERNAL_FUNCTION) {
8663
- #ifdef ZEND_WIN32
8664
- // TODO: ASLR may cause different addresses in different workers ???
8665
- return 0;
8666
- #endif
8667
- } else if (func->type == ZEND_USER_FUNCTION) {
8668
- if (!zend_accel_in_shm(func->op_array.opcodes)) {
8669
- /* op_array and op_array->opcodes are not persistent. We can't link. */
8670
- return 0;
8671
- }
8672
- } else {
8673
- ZEND_UNREACHABLE();
8694
+ if (func->type == ZEND_USER_FUNCTION
8695
+ && !zend_accel_in_shm(func->op_array.opcodes)) {
8696
+ /* op_array and op_array->opcodes are not persistent. We can't link. */
8674
8697
return 0;
8675
8698
}
8676
8699
@@ -8688,24 +8711,7 @@ static int zend_jit_init_fcall_guard(zend_jit_ctx *jit, uint32_t level, const ze
8688
8711
level--;
8689
8712
}
8690
8713
8691
- if (func->type == ZEND_USER_FUNCTION &&
8692
- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
8693
- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
8694
- !func->common.function_name)) {
8695
- const zend_op *opcodes = func->op_array.opcodes;
8696
-
8697
- // JIT: if (call->func.op_array.opcodes != opcodes) goto exit_addr;
8698
- ir_GUARD(
8699
- ir_EQ(
8700
- ir_LOAD_A(ir_ADD_OFFSET(ir_LOAD_A(jit_CALL(call, func)), offsetof(zend_op_array, opcodes))),
8701
- ir_CONST_ADDR(opcodes)),
8702
- ir_CONST_ADDR(exit_addr));
8703
- } else {
8704
- // JIT: if (call->func != func) goto exit_addr;
8705
- ir_GUARD(ir_EQ(ir_LOAD_A(jit_CALL(call, func)), ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8706
- }
8707
-
8708
- return 1;
8714
+ return zend_jit_func_guard(jit, ir_LOAD_A(jit_CALL(call, func)), func, exit_addr);
8709
8715
}
8710
8716
8711
8717
static int zend_jit_init_fcall(zend_jit_ctx *jit, const zend_op *opline, uint32_t b, const zend_op_array *op_array, zend_ssa *ssa, const zend_ssa_op *ssa_op, int call_level, zend_jit_trace_rec *trace, int checked_stack)
@@ -8812,17 +8818,8 @@ static int zend_jit_init_fcall(zend_jit_ctx *jit, const zend_op *opline, uint32_
8812
8818
}
8813
8819
if (!func || opline->opcode == ZEND_INIT_FCALL) {
8814
8820
ir_GUARD(ref, ir_CONST_ADDR(exit_addr));
8815
- } else if (func->type == ZEND_USER_FUNCTION
8816
- && !(func->common.fn_flags & ZEND_ACC_IMMUTABLE)) {
8817
- const zend_op *opcodes = func->op_array.opcodes;
8818
-
8819
- ir_GUARD(
8820
- ir_EQ(
8821
- ir_LOAD_A(ir_ADD_OFFSET(ref, offsetof(zend_op_array, opcodes))),
8822
- ir_CONST_ADDR(opcodes)),
8823
- ir_CONST_ADDR(exit_addr));
8824
- } else {
8825
- ir_GUARD(ir_EQ(ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
8821
+ } else if (!zend_jit_func_guard(jit, ref, func, exit_addr)) {
8822
+ return 0;
8826
8823
}
8827
8824
} else {
8828
8825
jit_SET_EX_OPLINE(jit, opline);
@@ -9028,11 +9025,7 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
9028
9025
if ((!func || zend_jit_may_be_modified(func, op_array))
9029
9026
&& trace
9030
9027
&& trace->op == ZEND_JIT_TRACE_INIT_CALL
9031
- && trace->func
9032
- #ifdef _WIN32
9033
- && trace->func->type != ZEND_INTERNAL_FUNCTION
9034
- #endif
9035
- ) {
9028
+ && trace->func) {
9036
9029
int32_t exit_point;
9037
9030
const void *exit_addr;
9038
9031
@@ -9047,19 +9040,8 @@ static int zend_jit_init_method_call(zend_jit_ctx *jit,
9047
9040
9048
9041
func = (zend_function*)trace->func;
9049
9042
9050
- if (func->type == ZEND_USER_FUNCTION &&
9051
- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
9052
- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
9053
- !func->common.function_name)) {
9054
- const zend_op *opcodes = func->op_array.opcodes;
9055
-
9056
- ir_GUARD(
9057
- ir_EQ(
9058
- ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
9059
- ir_CONST_ADDR(opcodes)),
9060
- ir_CONST_ADDR(exit_addr));
9061
- } else {
9062
- ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
9043
+ if (!zend_jit_func_guard(jit, func_ref, func, exit_addr)) {
9044
+ return 0;
9063
9045
}
9064
9046
}
9065
9047
@@ -9213,11 +9195,7 @@ static int zend_jit_init_static_method_call(zend_jit_ctx *jit,
9213
9195
if ((!func || zend_jit_may_be_modified(func, op_array))
9214
9196
&& trace
9215
9197
&& trace->op == ZEND_JIT_TRACE_INIT_CALL
9216
- && trace->func
9217
- #ifdef _WIN32
9218
- && trace->func->type != ZEND_INTERNAL_FUNCTION
9219
- #endif
9220
- ) {
9198
+ && trace->func) {
9221
9199
int32_t exit_point;
9222
9200
const void *exit_addr;
9223
9201
@@ -9232,19 +9210,8 @@ static int zend_jit_init_static_method_call(zend_jit_ctx *jit,
9232
9210
9233
9211
func = (zend_function*)trace->func;
9234
9212
9235
- if (func->type == ZEND_USER_FUNCTION &&
9236
- (!(func->common.fn_flags & ZEND_ACC_IMMUTABLE) ||
9237
- (func->common.fn_flags & ZEND_ACC_CLOSURE) ||
9238
- !func->common.function_name)) {
9239
- const zend_op *opcodes = func->op_array.opcodes;
9240
-
9241
- ir_GUARD(
9242
- ir_EQ(
9243
- ir_LOAD_A(ir_ADD_OFFSET(func_ref, offsetof(zend_op_array, opcodes))),
9244
- ir_CONST_ADDR(opcodes)),
9245
- ir_CONST_ADDR(exit_addr));
9246
- } else {
9247
- ir_GUARD(ir_EQ(func_ref, ir_CONST_ADDR(func)), ir_CONST_ADDR(exit_addr));
9213
+ if (!zend_jit_func_guard(jit, func_ref, func, exit_addr)) {
9214
+ return 0;
9248
9215
}
9249
9216
}
9250
9217
0 commit comments