mirror of
https://github.com/php/php-src.git
synced 2026-04-27 10:16:41 +02:00
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: JIT: Fixed result when assigning to typed reference
This commit is contained in:
@@ -5556,6 +5556,7 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
|
||||
const zend_op *opline,
|
||||
zend_uchar val_type,
|
||||
zend_jit_addr val_addr,
|
||||
zend_jit_addr res_addr,
|
||||
bool check_exception)
|
||||
{
|
||||
| // 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,
|
||||
} else {
|
||||
ZEND_UNREACHABLE();
|
||||
}
|
||||
if (res_addr) {
|
||||
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_X0, 0); // RETVAL
|
||||
|
||||
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_REG1, ZREG_REG2, ZREG_TMP1, ZREG_TMP2, ZREG_FPR0
|
||||
| TRY_ADDREF -1, REG1w, REG2, TMP1w
|
||||
}
|
||||
if (check_exception) {
|
||||
| // if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
| MEM_LOAD_64_ZTS ldr, REG0, executor_globals, exception, TMP1
|
||||
@@ -5710,7 +5717,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
|
||||
| IF_NOT_Z_TYPE Rx(ref_reg), IS_REFERENCE, >1, TMP1w
|
||||
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
|
||||
| GET_Z_PTR FCARG1x, Rx(ref_reg)
|
||||
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, check_exception)) {
|
||||
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, res_addr, check_exception)) {
|
||||
return 0;
|
||||
}
|
||||
| add Rx(ref_reg), FCARG1x, #offsetof(zend_reference, val)
|
||||
|
||||
@@ -1752,30 +1752,30 @@ static void ZEND_FASTCALL zend_jit_vm_stack_free_args_helper(zend_execute_data *
|
||||
zend_vm_stack_free_args(call);
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_jit_assign_to_typed_ref_helper(zend_reference *ref, zval *value, zend_uchar value_type)
|
||||
static zend_always_inline zval* zend_jit_assign_to_typed_ref_helper(zend_reference *ref, zval *value, zend_uchar value_type)
|
||||
{
|
||||
zval variable;
|
||||
|
||||
ZVAL_REF(&variable, ref);
|
||||
zend_assign_to_variable(&variable, value, value_type, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)));
|
||||
return zend_assign_to_variable(&variable, value, value_type, ZEND_CALL_USES_STRICT_TYPES(EG(current_execute_data)));
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_assign_const_to_typed_ref(zend_reference *ref, zval *value)
|
||||
static zval* ZEND_FASTCALL zend_jit_assign_const_to_typed_ref(zend_reference *ref, zval *value)
|
||||
{
|
||||
zend_jit_assign_to_typed_ref_helper(ref, value, IS_CONST);
|
||||
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_CONST);
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_assign_tmp_to_typed_ref(zend_reference *ref, zval *value)
|
||||
static zval* ZEND_FASTCALL zend_jit_assign_tmp_to_typed_ref(zend_reference *ref, zval *value)
|
||||
{
|
||||
zend_jit_assign_to_typed_ref_helper(ref, value, IS_TMP_VAR);
|
||||
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_TMP_VAR);
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_assign_var_to_typed_ref(zend_reference *ref, zval *value)
|
||||
static zval* ZEND_FASTCALL zend_jit_assign_var_to_typed_ref(zend_reference *ref, zval *value)
|
||||
{
|
||||
zend_jit_assign_to_typed_ref_helper(ref, value, IS_VAR);
|
||||
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_VAR);
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref, zval *value)
|
||||
static zval* ZEND_FASTCALL zend_jit_assign_cv_to_typed_ref(zend_reference *ref, zval *value)
|
||||
{
|
||||
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
|
||||
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
|
||||
zend_jit_undefined_op_helper(var);
|
||||
value = &EG(uninitialized_zval);
|
||||
}
|
||||
zend_jit_assign_to_typed_ref_helper(ref, value, IS_CV);
|
||||
return zend_jit_assign_to_typed_ref_helper(ref, value, IS_CV);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4762,7 +4762,12 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
|
||||
&& ssa->vars[ssa_op->op1_def].alias == NO_ALIAS) {
|
||||
ssa->var_info[ssa_op->op1_def].guarded_reference = 1;
|
||||
}
|
||||
if (!zend_jit_assign_to_typed_ref(&dasm_state, opline, opline->op2_type, op2_addr, 1)) {
|
||||
if (opline->result_type == IS_UNUSED) {
|
||||
res_addr = 0;
|
||||
} else {
|
||||
res_addr = RES_REG_ADDR();
|
||||
}
|
||||
if (!zend_jit_assign_to_typed_ref(&dasm_state, opline, opline->op2_type, op2_addr, res_addr, 1)) {
|
||||
goto jit_failure;
|
||||
}
|
||||
op1_def_addr = op1_addr;
|
||||
|
||||
@@ -6043,7 +6043,8 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
|
||||
const zend_op *opline,
|
||||
zend_uchar val_type,
|
||||
zend_jit_addr val_addr,
|
||||
bool check_exception)
|
||||
zend_jit_addr res_addr,
|
||||
bool check_exception)
|
||||
{
|
||||
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
|
||||
| cmp aword [FCARG1a + offsetof(zend_reference, sources.ptr)], 0
|
||||
@@ -6067,6 +6068,12 @@ static int zend_jit_assign_to_typed_ref(dasm_State **Dst,
|
||||
} else {
|
||||
ZEND_UNREACHABLE();
|
||||
}
|
||||
if (res_addr) {
|
||||
zend_jit_addr ret_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
|
||||
|
||||
| ZVAL_COPY_VALUE res_addr, -1, ret_addr, -1, ZREG_R1, ZREG_R2
|
||||
| TRY_ADDREF -1, ch, r2
|
||||
}
|
||||
if (check_exception) {
|
||||
| // if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
| MEM_CMP_ZTS aword, executor_globals, exception, 0, r0
|
||||
@@ -6196,7 +6203,7 @@ static int zend_jit_assign_to_variable(dasm_State **Dst,
|
||||
| IF_NOT_Z_TYPE, Ra(ref_reg), IS_REFERENCE, >1
|
||||
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
|
||||
| GET_Z_PTR FCARG1a, Ra(ref_reg)
|
||||
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, check_exception)) {
|
||||
if (!zend_jit_assign_to_typed_ref(Dst, opline, val_type, val_addr, res_addr, check_exception)) {
|
||||
return 0;
|
||||
}
|
||||
| lea Ra(ref_reg), [FCARG1a + offsetof(zend_reference, val)]
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
--TEST--
|
||||
JIT ASSIGN: Assign to typed reference should return modified value
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
opcache.file_update_protection=0
|
||||
opcache.jit_buffer_size=1M
|
||||
opcache.protect_memory=1
|
||||
--FILE--
|
||||
<?php
|
||||
class Test {
|
||||
public ?string $prop;
|
||||
}
|
||||
function test($val) {
|
||||
$obj = new Test;
|
||||
$ref =& $obj->prop;
|
||||
var_dump($ref = $val);
|
||||
}
|
||||
test(0);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "0"
|
||||
Reference in New Issue
Block a user