Skip to content

Commit 95c9cd6

Browse files
committed
Backport fix for phpGH-9011
1 parent e532d9a commit 95c9cd6

File tree

2 files changed

+77
-14
lines changed

2 files changed

+77
-14
lines changed

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9240,19 +9240,11 @@ static int zend_jit_init_fcall_guard(dasm_State **Dst, uint32_t level, const zen
92409240
int32_t exit_point;
92419241
const void *exit_addr;
92429242

9243-
if (func->type == ZEND_INTERNAL_FUNCTION) {
9244-
#ifdef ZEND_WIN32
9245-
// TODO: ASLR may cause different addresses in different workers ???
9246-
return 0;
9247-
#endif
9248-
} else if (func->type == ZEND_USER_FUNCTION) {
9243+
if (func->type == ZEND_USER_FUNCTION) {
92499244
if (!zend_accel_in_shm(func->op_array.opcodes)) {
92509245
/* op_array and op_array->opcodes are not persistent. We can't link. */
92519246
return 0;
92529247
}
9253-
} else {
9254-
ZEND_UNREACHABLE();
9255-
return 0;
92569248
}
92579249

92589250
exit_point = zend_jit_trace_get_exit_point(to_opline, ZEND_JIT_EXIT_POLYMORPHISM);
@@ -9286,6 +9278,22 @@ static int zend_jit_init_fcall_guard(dasm_State **Dst, uint32_t level, const zen
92869278
| cmp aword [r1 + offsetof(zend_op_array, opcodes)], opcodes
92879279
| .endif
92889280
| jne &exit_addr
9281+
#ifdef _WIN32
9282+
} else if (func->type == ZEND_INTERNAL_FUNCTION) {
9283+
const zif_handler *handler = func->internal_function.handler;
9284+
9285+
| .if X64
9286+
|| if (!IS_SIGNED_32BIT(handler)) {
9287+
| mov64 r2, ((ptrdiff_t)handler)
9288+
| cmp aword [r1 + offsetof(zend_internal_function, handler)], r2
9289+
|| } else {
9290+
| cmp aword [r1 + offsetof(zend_internal_function, handler)], handler
9291+
|| }
9292+
| .else
9293+
| cmp aword [r1 + offsetof(zend_internal_function, handler)], handler
9294+
| .endif
9295+
| jne &exit_addr
9296+
#endif
92899297
} else {
92909298
| .if X64
92919299
|| if (!IS_SIGNED_32BIT(func)) {
@@ -9432,6 +9440,22 @@ static int zend_jit_init_fcall(dasm_State **Dst, const zend_op *opline, uint32_t
94329440
| cmp aword [r0 + offsetof(zend_op_array, opcodes)], opcodes
94339441
| .endif
94349442
| jz >3
9443+
#ifdef _WIN32
9444+
} else if (func->type == ZEND_INTERNAL_FUNCTION) {
9445+
const zif_handler *handler = func->internal_function.handler;
9446+
9447+
| .if X64
9448+
|| if (!IS_SIGNED_32BIT(handler)) {
9449+
| mov64 r1, ((ptrdiff_t)handler)
9450+
| cmp aword [r0 + offsetof(zend_internal_function, handler)], r1
9451+
|| } else {
9452+
| cmp aword [r0 + offsetof(zend_internal_function, handler)], handler
9453+
|| }
9454+
| .else
9455+
| cmp aword [r0 + offsetof(zend_internal_function, handler)], handler
9456+
| .endif
9457+
| jz >3
9458+
#endif
94359459
} else {
94369460
| .if X64
94379461
|| if (!IS_SIGNED_32BIT(func)) {
@@ -9618,11 +9642,7 @@ static int zend_jit_init_method_call(dasm_State **Dst,
96189642
if ((!func || zend_jit_may_be_modified(func, op_array))
96199643
&& trace
96209644
&& trace->op == ZEND_JIT_TRACE_INIT_CALL
9621-
&& trace->func
9622-
#ifdef _WIN32
9623-
&& trace->func->type != ZEND_INTERNAL_FUNCTION
9624-
#endif
9625-
) {
9645+
&& trace->func) {
96269646
int32_t exit_point;
96279647
const void *exit_addr;
96289648

@@ -9651,6 +9671,22 @@ static int zend_jit_init_method_call(dasm_State **Dst,
96519671
| cmp aword [r0 + offsetof(zend_op_array, opcodes)], opcodes
96529672
| .endif
96539673
| jne &exit_addr
9674+
#ifdef _WIN32
9675+
} else if (func->type == ZEND_INTERNAL_FUNCTION) {
9676+
const zif_handler *handler = func->internal_function.handler;
9677+
9678+
| .if X64
9679+
|| if (!IS_SIGNED_32BIT(handler)) {
9680+
| mov64 r1, ((ptrdiff_t)handler)
9681+
| cmp aword [r0 + offsetof(zend_internal_function, handler)], r1
9682+
|| } else {
9683+
| cmp aword [r0 + offsetof(zend_internal_function, handler)], handler
9684+
|| }
9685+
| .else
9686+
| cmp aword [r0 + offsetof(zend_internal_function, handler)], handler
9687+
| .endif
9688+
| jne &exit_addr
9689+
#endif
96549690
} else {
96559691
| .if X64
96569692
|| if (!IS_SIGNED_32BIT(func)) {

ext/opcache/tests/jit/gh9011.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-9011: Assertion failure with tracing JIT
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
--FILE--
8+
<?php
9+
$foo = [];
10+
$foo[] = new \Exception(); /* Native interface implemented Native instance */
11+
$foo[] = new class () implements \Stringable /* Native interface implemented User instance */
12+
{
13+
public function __toString(): string
14+
{
15+
return "bar";
16+
}
17+
};
18+
19+
foreach ($foo as $baz) {
20+
for ($i = 0; $i < 64; $i++) {
21+
$baz->__toString();
22+
}
23+
}
24+
?>
25+
DONE
26+
--EXPECT--
27+
DONE

0 commit comments

Comments
 (0)