mirror of
https://github.com/php/php-src.git
synced 2024-09-21 18:07:23 +00:00
Fix JIT typed property inc/dec
This was leaking memory for pre-inc/dec of a refcounted typed property if the result was not used. The code to do this was unnecessarily complicated, we can base this on the zend_jit_inc/dec_typed_prop() helper and copy to the result afterwards.
This commit is contained in:
parent
e588f24276
commit
770879702a
@ -2342,64 +2342,14 @@ static void ZEND_FASTCALL zend_jit_dec_typed_prop(zval *var_ptr, zend_property_i
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_pre_inc_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result)
|
||||
{
|
||||
zend_execute_data *execute_data = EG(current_execute_data);
|
||||
zval tmp;
|
||||
|
||||
if (!result) {
|
||||
result = &tmp;
|
||||
}
|
||||
|
||||
ZVAL_DEREF(var_ptr);
|
||||
zend_jit_inc_typed_prop(var_ptr, prop_info);
|
||||
ZVAL_COPY(result, var_ptr);
|
||||
|
||||
increment_function(var_ptr);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(result) == IS_LONG) {
|
||||
if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) {
|
||||
zend_long val = _zend_jit_throw_inc_prop_error(prop_info);
|
||||
ZVAL_LONG(var_ptr, val);
|
||||
}
|
||||
} else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) {
|
||||
zval_ptr_dtor(var_ptr);
|
||||
ZVAL_COPY_VALUE(var_ptr, result);
|
||||
ZVAL_UNDEF(result);
|
||||
} else if (result == &tmp) {
|
||||
zval_ptr_dtor(&tmp);
|
||||
}
|
||||
if (UNEXPECTED(result)) {
|
||||
ZVAL_COPY(result, var_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_pre_dec_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result)
|
||||
{
|
||||
zend_execute_data *execute_data = EG(current_execute_data);
|
||||
zval tmp;
|
||||
|
||||
if (!result) {
|
||||
result = &tmp;
|
||||
}
|
||||
|
||||
ZVAL_DEREF(var_ptr);
|
||||
zend_jit_dec_typed_prop(var_ptr, prop_info);
|
||||
ZVAL_COPY(result, var_ptr);
|
||||
|
||||
decrement_function(var_ptr);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(var_ptr) == IS_DOUBLE) && Z_TYPE_P(result) == IS_LONG) {
|
||||
if (!(ZEND_TYPE_FULL_MASK(prop_info->type) & MAY_BE_DOUBLE)) {
|
||||
zend_long val = _zend_jit_throw_dec_prop_error(prop_info);
|
||||
ZVAL_LONG(var_ptr, val);
|
||||
}
|
||||
} else if (UNEXPECTED(!zend_verify_property_type(prop_info, var_ptr, EX_USES_STRICT_TYPES()))) {
|
||||
zval_ptr_dtor(var_ptr);
|
||||
ZVAL_COPY_VALUE(var_ptr, result);
|
||||
ZVAL_UNDEF(result);
|
||||
} else if (result == &tmp) {
|
||||
zval_ptr_dtor(&tmp);
|
||||
}
|
||||
if (UNEXPECTED(result)) {
|
||||
ZVAL_COPY(result, var_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void ZEND_FASTCALL zend_jit_post_inc_typed_prop(zval *var_ptr, zend_property_info *prop_info, zval *result)
|
||||
@ -2475,8 +2425,7 @@ static void ZEND_FASTCALL zend_jit_pre_inc_obj_helper(zend_object *zobj, zend_st
|
||||
}
|
||||
|
||||
if (UNEXPECTED(prop_info)) {
|
||||
zend_jit_pre_inc_typed_prop(prop, prop_info, result);
|
||||
return;
|
||||
zend_jit_inc_typed_prop(prop, prop_info);
|
||||
} else {
|
||||
increment_function(prop);
|
||||
}
|
||||
@ -2544,8 +2493,7 @@ static void ZEND_FASTCALL zend_jit_pre_dec_obj_helper(zend_object *zobj, zend_st
|
||||
}
|
||||
|
||||
if (UNEXPECTED(prop_info)) {
|
||||
zend_jit_pre_dec_typed_prop(prop, prop_info, result);
|
||||
return;
|
||||
zend_jit_dec_typed_prop(prop, prop_info);
|
||||
} else {
|
||||
decrement_function(prop);
|
||||
}
|
||||
|
24
ext/opcache/tests/jit/inc_023.phpt
Normal file
24
ext/opcache/tests/jit/inc_023.phpt
Normal file
@ -0,0 +1,24 @@
|
||||
--TEST--
|
||||
PRE_INC/DEC refcounted typed property
|
||||
--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;
|
||||
}
|
||||
|
||||
$test = new Test;
|
||||
$test->prop = "a";
|
||||
++$test->prop;
|
||||
--$test->prop;
|
||||
var_dump(++$test->prop);
|
||||
var_dump(--$test->prop);
|
||||
?>
|
||||
--EXPECT--
|
||||
string(1) "c"
|
||||
string(1) "c"
|
Loading…
Reference in New Issue
Block a user