Skip to content

Commit

Permalink
JIT: Fixed result when assigning to typed reference
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Sep 28, 2021
1 parent d8c2ff6 commit 17b127a
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 12 deletions.
20 changes: 10 additions & 10 deletions ext/opcache/jit/zend_jit_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -1880,30 +1880,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;
Expand All @@ -1917,7 +1917,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);
}


Expand Down
7 changes: 6 additions & 1 deletion ext/opcache/jit/zend_jit_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -4527,7 +4527,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;
Expand Down
9 changes: 8 additions & 1 deletion ext/opcache/jit/zend_jit_x86.dasc
Original file line number Diff line number Diff line change
Expand Up @@ -5990,6 +5990,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,
zend_bool check_exception)
{
| // if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(variable_ptr)))) {
Expand All @@ -6014,6 +6015,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_OP2_1_ZTS cmp, aword, executor_globals, exception, 0, r0
Expand Down Expand Up @@ -6143,7 +6150,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)]
Expand Down
22 changes: 22 additions & 0 deletions ext/opcache/tests/jit/assign_041.phpt
Original file line number Diff line number Diff line change
@@ -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"

0 comments on commit 17b127a

Please sign in to comment.