Skip to content

Commit 214cd15

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: JIT: Fixed result when assigning to typed reference
2 parents 2b71df7 + 17b127a commit 214cd15

File tree

5 files changed

+55
-14
lines changed

5 files changed

+55
-14
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5556,6 +5556,7 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
55565556
const zend_op *opline,
55575557
zend_uchar val_type,
55585558
zend_jit_addr val_addr,
5559+
zend_jit_addr res_addr,
55595560
bool check_exception)
55605561
{
55615562
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
@@ -5580,6 +5581,12 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
55805581
} else {
55815582
ZEND_UNREACHABLE();
55825583
}
5584+
if (res_addr) {
5585+
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_X0, 0); // RETVAL
5586+
5587+
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_REG1, ZREG_REG2, ZREG_TMP1, ZREG_TMP2, ZREG_FPR0
5588+
| TRY_ADDREF -1, REG1w, REG2, TMP1w
5589+
}
55835590
if (check_exception) {
55845591
| // if (UNEXPECTED(EG(exception) != NULL)) {
55855592
| MEM_LOAD_64_ZTS ldr, REG0, executor_globals, exception, TMP1
@@ -5710,7 +5717,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
57105717
| IF_NOT_Z_TYPE Rx(ref_reg), IS_REFERENCE, >1, TMP1w
57115718
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
57125719
| GET_Z_PTR FCARG1x, Rx(ref_reg)
5713-
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, check_exception)) {
5720+
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, res_addr, check_exception)) {
57145721
return 0;
57155722
}
57165723
| add Rx(ref_reg), FCARG1x, #offsetof(zend_reference, val)

ext/opcache/jit/zend_jit_helpers.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1752,30 +1752,30 @@ static void ZEND_FASTCALL zend_jit_vm_stack_free_args_helper(zend_execute_data *
17521752
zend_vm_stack_free_args(call);
17531753
}
17541754

1755-
static zend_always_inline void zend_jit_assign_to_typed_ref_helper(zend_reference *ref, zval *value, zend_uchar value_type)
1755+
static zend_always_inline zval* zend_jit_assign_to_typed_ref_helper(zend_reference *ref, zval *value, zend_uchar value_type)
17561756
{
17571757
zval variable;
17581758

17591759
ZVAL_REF(&variable, ref);
1760-
zend_assign_to_variable(&variable, value, value_type, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)));
1760+
return zend_assign_to_variable(&variable, value, value_type, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)));
17611761
}
17621762

1763-
static void ZEND_FASTCALL zend_jit_assign_const_to_typed_ref(zend_reference *ref, zval *value)
1763+
static zval* ZEND_FASTCALL zend_jit_assign_const_to_typed_ref(zend_reference *ref, zval *value)
17641764
{
1765-
zend_jit_assign_to_typed_ref_helper(ref, value, IS_CONST);
1765+
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_CONST);
17661766
}
17671767

1768-
static void ZEND_FASTCALL zend_jit_assign_tmp_to_typed_ref(zend_reference *ref, zval *value)
1768+
static zval* ZEND_FASTCALL zend_jit_assign_tmp_to_typed_ref(zend_reference *ref, zval *value)
17691769
{
1770-
zend_jit_assign_to_typed_ref_helper(ref, value, IS_TMP_VAR);
1770+
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_TMP_VAR);
17711771
}
17721772

1773-
static void ZEND_FASTCALL zend_jit_assign_var_to_typed_ref(zend_reference *ref, zval *value)
1773+
static zval* ZEND_FASTCALL zend_jit_assign_var_to_typed_ref(zend_reference *ref, zval *value)
17741774
{
1775-
zend_jit_assign_to_typed_ref_helper(ref, value, IS_VAR);
1775+
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_VAR);
17761776
}
17771777

1778-
static void ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref, zval *value)
1778+
static zval* ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref, zval *value)
17791779
{
17801780
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
17811781
const zend_op *opline = EG(current_execute_data)->opline;
@@ -1789,7 +1789,7 @@ static void ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref, z
17891789
zend_jit_undefined_op_helper(var);
17901790
value = &EG(uninitialized_zval);
17911791
}
1792-
zend_jit_assign_to_typed_ref_helper(ref, value, IS_CV);
1792+
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_CV);
17931793
}
17941794

17951795

ext/opcache/jit/zend_jit_trace.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4762,7 +4762,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
47624762
&& ssa->vars[ssa_op->op1_def].alias == NO_ALIAS) {
47634763
ssa->var_info[ssa_op->op1_def].guarded_reference = 1;
47644764
}
4765-
if (!zend_jit_assign_to_typed_ref(&dasm_state, opline, opline->op2_type, op2_addr, 1)) {
4765+
if (opline->result_type == IS_UNUSED) {
4766+
res_addr = 0;
4767+
} else {
4768+
res_addr = RES_REG_ADDR();
4769+
}
4770+
if (!zend_jit_assign_to_typed_ref(&dasm_state, opline, opline->op2_type, op2_addr, res_addr, 1)) {
47664771
goto jit_failure;
47674772
}
47684773
op1_def_addr = op1_addr;

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6043,7 +6043,8 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
60436043
const zend_op *opline,
60446044
zend_uchar val_type,
60456045
zend_jit_addr val_addr,
6046-
bool check_exception)
6046+
zend_jit_addr res_addr,
6047+
bool check_exception)
60476048
{
60486049
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
60496050
| cmp aword [FCARG1a + offsetof(zend_reference, sources.ptr)], 0
@@ -6067,6 +6068,12 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
60676068
} else {
60686069
ZEND_UNREACHABLE();
60696070
}
6071+
if (res_addr) {
6072+
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
6073+
6074+
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_R1, ZREG_R2
6075+
| TRY_ADDREF -1, ch, r2
6076+
}
60706077
if (check_exception) {
60716078
| // if (UNEXPECTED(EG(exception) != NULL)) {
60726079
| MEM_CMP_ZTS aword, executor_globals, exception, 0, r0
@@ -6196,7 +6203,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
61966203
| IF_NOT_Z_TYPE, Ra(ref_reg), IS_REFERENCE, >1
61976204
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
61986205
| GET_Z_PTR FCARG1a, Ra(ref_reg)
6199-
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, check_exception)) {
6206+
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, res_addr, check_exception)) {
62006207
return 0;
62016208
}
62026209
| lea Ra(ref_reg), [FCARG1a + offsetof(zend_reference, val)]

ext/opcache/tests/jit/assign_041.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
JIT ASSIGN: Assign to typed reference should return modified value
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.file_update_protection=0
7+
opcache.jit_buffer_size=1M
8+
opcache.protect_memory=1
9+
--FILE--
10+
<?php
11+
class Test {
12+
public ?string $prop;
13+
}
14+
function test($val) {
15+
$obj = new Test;
16+
$ref =& $obj->prop;
17+
var_dump($ref = $val);
18+
}
19+
test(0);
20+
?>
21+
--EXPECT--
22+
string(1) "0"

0 commit comments

Comments
 (0)