1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

VAR|TMP overhaul (GH-20628)

The aim of this PR is twofold:

- Reduce the number of highly similar TMP|VAR handlers
- Avoid ZVAL_DEREF in most of these cases

This is achieved by guaranteeing that all zend_compile_expr() calls, as well as
all other compile calls with BP_VAR_{R,IS}, will result in a TMP variable. This
implies that the result will not contain an IS_INDIRECT or IS_REFERENCE value,
which was mostly already the case, with two exceptions:

- Calls to return-by-reference functions. Because return-by-reference functions
  are quite rare, this is solved by delegating the DEREF to the RETURN_BY_REF
  handler, which will examine the stack to check whether the caller expects a
  VAR or TMP to understand whether the DEREF is needed. Internal functions will
  also need to adjust by calling the zend_return_unwrap_ref() function.

- By-reference assignments, including both $a = &$b, as well as $a = [&$b]. When
  the result of these expressions is used in a BP_VAR_R context, the reference
  is unwrapped via a ZEND_QM_ASSIGN opcode beforehand. This is exceptionally
  rare.

Closes GH-20628
This commit is contained in:
Ilija Tovilo
2026-01-31 19:44:56 +01:00
committed by GitHub
parent 927b9eecb6
commit 6173a9a109
48 changed files with 13984 additions and 20472 deletions

View File

@@ -56,6 +56,10 @@ PHP 8.6 INTERNALS UPGRADE NOTES
node.
. The zend_exception_save() and zend_exception_restore() functions were
removed.
. Internal functions that return by reference are now expected to
automatically unwrap references when the result of the call is stored in an
IS_TMP_VAR variable. This may be achieved by calling the
zend_return_unwrap_ref() function.
========================
2. Build system changes

View File

@@ -289,20 +289,7 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
MAKE_NOP(opline);
++(*opt_count);
break;
case ZEND_ASSIGN:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_PRE_INC_STATIC_PROP:
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_QM_ASSIGN:
if (src < op_array->opcodes + block->start) {
break;
}
@@ -310,8 +297,26 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array
VAR_SOURCE(opline->op1) = NULL;
MAKE_NOP(opline);
++(*opt_count);
if (src->op1_type & (IS_VAR|IS_TMP_VAR)) {
src->opcode = ZEND_FREE;
} else if (src->op1_type == IS_CONST) {
MAKE_NOP(src);
} else if (src->op1_type == IS_CV) {
src->opcode = ZEND_CHECK_VAR;
SET_UNUSED(src->result);
}
break;
default:
if (!zend_op_may_elide_result(src->opcode)) {
break;
}
if (src < op_array->opcodes + block->start) {
break;
}
src->result_type = IS_UNUSED;
VAR_SOURCE(opline->op1) = NULL;
MAKE_NOP(opline);
++(*opt_count);
break;
}
}
@@ -985,6 +990,8 @@ optimize_const_unary_op:
src = VAR_SOURCE(opline->op1);
if (src &&
src->opcode != ZEND_COPY_TMP &&
/* See gh20628_borked_live_range_calc.phpt. */
src->opcode != ZEND_NEW &&
src->opcode != ZEND_ADD_ARRAY_ELEMENT &&
src->opcode != ZEND_ADD_ARRAY_UNPACK &&
(src->opcode != ZEND_DECLARE_LAMBDA_FUNCTION ||

View File

@@ -162,10 +162,16 @@ static inline bool may_have_side_effects(
case ZEND_EXT_FCALL_END:
case ZEND_TICKS:
case ZEND_YIELD:
case ZEND_YIELD_FROM:
case ZEND_VERIFY_NEVER_TYPE:
/* Intrinsic side effects */
return true;
case ZEND_YIELD_FROM: {
uint32_t t1 = OP1_INFO();
if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY && MAY_BE_EMPTY_ONLY(t1)) {
return false;
}
return true;
}
case ZEND_DO_FCALL:
case ZEND_DO_FCALL_BY_NAME:
case ZEND_DO_ICALL:

View File

@@ -5336,6 +5336,13 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op
return 1;
}
return 0;
case ZEND_YIELD_FROM: {
uint32_t t1 = OP1_INFO();
if ((t1 & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY && MAY_BE_EMPTY_ONLY(t1)) {
return false;
}
return true;
}
default:
return 1;
}

View File

@@ -0,0 +1,12 @@
--TEST--
Nullsafe operator does not support BP_VAR_W
--FILE--
<?php
function &test($foo) {
return $foo?->bar();
}
?>
--EXPECTF--
Fatal error: Cannot take reference of a nullsafe chain in %s on line %d

View File

@@ -0,0 +1,22 @@
--TEST--
Pipes support return-by-reference
--FILE--
<?php
function &foo($val) {
global $x;
$x = $val;
return $x;
}
function &bar() {
return 42 |> foo(...);
}
$xRef = &bar();
$xRef++;
var_dump($x);
?>
--EXPECT--
int(43)

View File

@@ -0,0 +1,71 @@
--TEST--
Missing separation for ASSIGN_DIM with ref OP_DATA
--FILE--
<?php
function a() {
$a[] = $b[] = &$a;
var_dump($a, $b);
}
function b() {
$a = [];
$b = [];
$a[] = $b[] = &$a;
var_dump($a, $b);
}
function c() {
$a[] = $b = &$a;
var_dump($a, $b);
}
function d() {
$a = $b[] = &$a;
var_dump($a, $b);
}
a();
b();
c();
d();
?>
--EXPECT--
array(1) {
[0]=>
NULL
}
array(1) {
[0]=>
&array(1) {
[0]=>
NULL
}
}
array(1) {
[0]=>
array(0) {
}
}
array(1) {
[0]=>
&array(1) {
[0]=>
array(0) {
}
}
}
array(1) {
[0]=>
NULL
}
array(1) {
[0]=>
NULL
}
NULL
array(1) {
[0]=>
&NULL
}

View File

@@ -0,0 +1,3 @@
<?php
$this->bar();

View File

@@ -0,0 +1,22 @@
--TEST--
Invalid opcode for method call with FETCH_THIS
--FILE--
<?php
class Foo {
public function bar() {
var_dump($this, __METHOD__);
}
public function test() {
require __DIR__ . '/gh20628_004.inc';
}
}
(new Foo)->test();
?>
--EXPECTF--
object(Foo)#%d (0) {
}
string(8) "Foo::bar"

View File

@@ -287,7 +287,7 @@ Unsupported operand types: stdClass * stdClass
Unsupported operand types: stdClass * resource
Unsupported operand types: stdClass * string
Unsupported operand types: resource * array
Unsupported operand types: stdClass * resource
Unsupported operand types: resource * stdClass
Unsupported operand types: resource * resource
Unsupported operand types: resource * string
Unsupported operand types: string * array
@@ -753,7 +753,7 @@ Unsupported operand types: stdClass & stdClass
Unsupported operand types: stdClass & resource
Unsupported operand types: stdClass & string
Unsupported operand types: resource & array
Unsupported operand types: stdClass & resource
Unsupported operand types: resource & stdClass
Unsupported operand types: resource & resource
Unsupported operand types: resource & string
Unsupported operand types: string & array
@@ -828,7 +828,7 @@ Unsupported operand types: stdClass | stdClass
Unsupported operand types: stdClass | resource
Unsupported operand types: stdClass | string
Unsupported operand types: resource | array
Unsupported operand types: stdClass | resource
Unsupported operand types: resource | stdClass
Unsupported operand types: resource | resource
Unsupported operand types: resource | string
Unsupported operand types: string | array
@@ -903,7 +903,7 @@ Unsupported operand types: stdClass ^ stdClass
Unsupported operand types: stdClass ^ resource
Unsupported operand types: stdClass ^ string
Unsupported operand types: resource ^ array
Unsupported operand types: stdClass ^ resource
Unsupported operand types: resource ^ stdClass
Unsupported operand types: resource ^ resource
Unsupported operand types: resource ^ string
Unsupported operand types: string ^ array

View File

@@ -9,7 +9,7 @@ if (!function_exists('zend_test_zend_call_stack_get')) die("skip zend_test_zend_
--EXTENSIONS--
zend_test
--INI--
zend.max_allowed_stack_size=128K
zend.max_allowed_stack_size=64K
--FILE--
<?php

View File

@@ -339,7 +339,7 @@ static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ {
fcc.called_scope = zend_get_called_scope(EG(current_execute_data));
zend_call_function(&fci, &fcc);
zend_return_unwrap_ref(EG(current_execute_data), return_value);
zval_ptr_dtor(&fci.params[1]);
}
/* }}} */

View File

@@ -101,7 +101,7 @@ static zend_op *zend_compile_var(znode *result, zend_ast *ast, uint32_t type, bo
static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type, bool by_ref);
static void zend_compile_expr(znode *result, zend_ast *ast);
static void zend_compile_stmt(zend_ast *ast);
static void zend_compile_assign(znode *result, zend_ast *ast);
static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt, uint32_t type);
#ifdef ZEND_CHECK_STACK_LIMIT
zend_never_inline static void zend_stack_limit_error(void)
@@ -753,6 +753,36 @@ static inline void zend_end_loop(int cont_addr, const znode *var_node) /* {{{ */
}
/* }}} */
bool zend_op_may_elide_result(uint8_t opcode)
{
switch (opcode) {
case ZEND_ASSIGN:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC_STATIC_PROP:
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
case ZEND_DO_FCALL:
case ZEND_DO_ICALL:
case ZEND_DO_UCALL:
case ZEND_DO_FCALL_BY_NAME:
case ZEND_YIELD:
case ZEND_YIELD_FROM:
case ZEND_INCLUDE_OR_EVAL:
return true;
default:
return false;
}
}
static void zend_do_free(znode *op1) /* {{{ */
{
if (op1->op_type == IS_TMP_VAR) {
@@ -779,22 +809,12 @@ static void zend_do_free(znode *op1) /* {{{ */
opline->opcode -= 2;
SET_UNUSED(opline->result);
return;
case ZEND_ASSIGN:
case ZEND_ASSIGN_DIM:
case ZEND_ASSIGN_OBJ:
case ZEND_ASSIGN_STATIC_PROP:
case ZEND_ASSIGN_OP:
case ZEND_ASSIGN_DIM_OP:
case ZEND_ASSIGN_OBJ_OP:
case ZEND_ASSIGN_STATIC_PROP_OP:
case ZEND_PRE_INC_STATIC_PROP:
case ZEND_PRE_DEC_STATIC_PROP:
case ZEND_PRE_INC_OBJ:
case ZEND_PRE_DEC_OBJ:
case ZEND_PRE_INC:
case ZEND_PRE_DEC:
SET_UNUSED(opline->result);
return;
default:
if (zend_op_may_elide_result(opline->opcode)) {
SET_UNUSED(opline->result);
return;
}
break;
}
}
@@ -2578,7 +2598,9 @@ static void zend_emit_jmp_null(znode *obj_node, uint32_t bp_type)
zend_stack_push(&CG(short_circuiting_opnums), &jmp_null_opnum);
}
static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */
static inline bool zend_is_variable_or_call(const zend_ast *ast);
static void zend_compile_memoized_expr(znode *result, zend_ast *expr, uint32_t type) /* {{{ */
{
const zend_memoize_mode memoize_mode = CG(memoize_mode);
if (memoize_mode == ZEND_MEMOIZE_COMPILE) {
@@ -2586,7 +2608,11 @@ static void zend_compile_memoized_expr(znode *result, zend_ast *expr) /* {{{ */
/* Go through normal compilation */
CG(memoize_mode) = ZEND_MEMOIZE_NONE;
zend_compile_expr(result, expr);
if (zend_is_variable_or_call(expr)) {
zend_compile_var(result, expr, type, /* by_ref */ false);
} else {
zend_compile_expr(result, expr);
}
CG(memoize_mode) = ZEND_MEMOIZE_COMPILE;
if (result->op_type == IS_VAR) {
@@ -2709,13 +2735,24 @@ void zend_emit_final_return(bool return_one) /* {{{ */
}
/* }}} */
static bool zend_propagate_list_refs(zend_ast *ast);
static inline bool zend_is_variable(const zend_ast *ast) /* {{{ */
{
return ast->kind == ZEND_AST_VAR
if (ast->kind == ZEND_AST_VAR
|| ast->kind == ZEND_AST_DIM
|| ast->kind == ZEND_AST_PROP
|| ast->kind == ZEND_AST_NULLSAFE_PROP
|| ast->kind == ZEND_AST_STATIC_PROP;
|| ast->kind == ZEND_AST_STATIC_PROP
|| ast->kind == ZEND_AST_ASSIGN_REF) {
return true;
}
if (ast->kind == ZEND_AST_ASSIGN
&& UNEXPECTED(ast->child[0]->kind == ZEND_AST_ARRAY)
&& zend_propagate_list_refs(ast->child[0])) {
return true;
}
return false;
}
/* }}} */
@@ -3126,7 +3163,11 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t
if (this_guaranteed_exists()) {
obj_node.op_type = IS_UNUSED;
} else {
zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL);
opline = zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL);
if ((type == BP_VAR_R) || (type == BP_VAR_IS)) {
opline->result_type = IS_TMP_VAR;
obj_node.op_type = IS_TMP_VAR;
}
}
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
@@ -3290,7 +3331,7 @@ static bool list_is_keyed(const zend_ast_list *list)
}
static void zend_compile_list_assign(
znode *result, zend_ast *ast, znode *expr_node, zend_ast_attr array_style) /* {{{ */
znode *result, zend_ast *ast, znode *expr_node, zend_ast_attr array_style, uint32_t type) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
uint32_t i;
@@ -3350,6 +3391,10 @@ static void zend_compile_list_assign(
opline = zend_emit_op(&fetch_result,
elem_ast->attr ? (expr_node->op_type == IS_CV ? ZEND_FETCH_DIM_W : ZEND_FETCH_LIST_W) : ZEND_FETCH_LIST_R, expr_node, &dim_node);
if (opline->opcode == ZEND_FETCH_LIST_R) {
opline->result_type = IS_TMP_VAR;
fetch_result.op_type = IS_TMP_VAR;
}
if (dim_node.op_type == IS_CONST) {
zend_handle_numeric_dim(opline, &dim_node);
@@ -3359,7 +3404,7 @@ static void zend_compile_list_assign(
zend_emit_op(&fetch_result, ZEND_MAKE_REF, &fetch_result, NULL);
}
if (var_ast->kind == ZEND_AST_ARRAY) {
zend_compile_list_assign(NULL, var_ast, &fetch_result, var_ast->attr);
zend_compile_list_assign(NULL, var_ast, &fetch_result, var_ast->attr, type);
} else if (elem_ast->attr) {
zend_emit_assign_ref_znode(var_ast, &fetch_result);
} else {
@@ -3372,7 +3417,12 @@ static void zend_compile_list_assign(
}
if (result) {
*result = *expr_node;
if ((type == BP_VAR_R || type == BP_VAR_IS) && expr_node->op_type == IS_VAR) {
/* Deref. */
zend_emit_op_tmp(result, ZEND_QM_ASSIGN, expr_node, NULL);
} else {
*result = *expr_node;
}
} else {
zend_do_free(expr_node);
}
@@ -3443,7 +3493,7 @@ static void zend_compile_expr_with_potential_assign_to_self(
}
}
static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
static void zend_compile_assign(znode *result, zend_ast *ast, bool stmt, uint32_t type) /* {{{ */
{
zend_ast *var_ast = ast->child[0];
zend_ast *expr_ast = ast->child[1];
@@ -3533,14 +3583,17 @@ static void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
}
}
zend_compile_list_assign(result, var_ast, &expr_node, var_ast->attr);
zend_compile_list_assign(!stmt ? result : NULL, var_ast, &expr_node, var_ast->attr, type);
if (stmt) {
result->op_type = IS_UNUSED;
}
return;
EMPTY_SWITCH_DEFAULT_CASE();
}
}
/* }}} */
static void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
static void zend_compile_assign_ref(znode *result, zend_ast *ast, uint32_t type) /* {{{ */
{
zend_ast *target_ast = ast->child[0];
zend_ast *source_ast = ast->child[1];
@@ -3587,28 +3640,40 @@ static void zend_compile_assign_ref(znode *result, zend_ast *ast) /* {{{ */
opline->opcode = ZEND_ASSIGN_OBJ_REF;
opline->extended_value &= ~ZEND_FETCH_REF;
opline->extended_value |= flags;
if (result) {
*result = target_node;
} else {
SET_UNUSED(opline->result);
}
zend_emit_op_data(&source_node);
*result = target_node;
} else if (opline && opline->opcode == ZEND_FETCH_STATIC_PROP_W) {
opline->opcode = ZEND_ASSIGN_STATIC_PROP_REF;
opline->extended_value &= ~ZEND_FETCH_REF;
opline->extended_value |= flags;
if (result) {
*result = target_node;
} else {
SET_UNUSED(opline->result);
}
zend_emit_op_data(&source_node);
*result = target_node;
} else {
opline = zend_emit_op(result, ZEND_ASSIGN_REF, &target_node, &source_node);
opline->extended_value = flags;
}
if (result && (type == BP_VAR_R || type == BP_VAR_IS)) {
/* Deref. */
znode tmp_result = *result;
zend_emit_op_tmp(result, ZEND_QM_ASSIGN, &tmp_result, NULL);
}
}
/* }}} */
static inline void zend_emit_assign_ref_znode(zend_ast *var_ast, const znode *value_node) /* {{{ */
{
znode dummy_node;
zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN_REF, var_ast,
zend_ast_create_znode(value_node));
zend_compile_expr(&dummy_node, assign_ast);
zend_do_free(&dummy_node);
zend_compile_stmt(assign_ast);
}
/* }}} */
@@ -3785,7 +3850,9 @@ static uint32_t zend_compile_args(
/* Treat passing of $GLOBALS the same as passing a call.
* This will error at runtime if the argument is by-ref. */
if (zend_is_call(arg) || is_globals_fetch(arg)) {
zend_compile_var(&arg_node, arg, BP_VAR_R, false);
uint32_t type = is_globals_fetch(arg) || (fbc && !ARG_SHOULD_BE_SENT_BY_REF(fbc, arg_num))
? BP_VAR_R : BP_VAR_FUNC_ARG;
zend_compile_var(&arg_node, arg, type, /* by_ref */ false);
if (arg_node.op_type & (IS_CONST|IS_TMP_VAR)) {
/* Function call was converted into builtin instruction */
if (!fbc || ARG_MUST_BE_SENT_BY_REF(fbc, arg_num)) {
@@ -3933,7 +4000,7 @@ ZEND_API uint8_t zend_get_call_op(const zend_op *init_op, const zend_function *f
}
/* }}} */
static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const zend_function *fbc, uint32_t lineno) /* {{{ */
static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const zend_function *fbc, uint32_t lineno, uint32_t type) /* {{{ */
{
zend_op *opline;
uint32_t opnum_init = get_next_op_number() - 1;
@@ -3975,8 +4042,9 @@ static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const ze
opline = &CG(active_op_array)->opcodes[opnum_init];
opline->extended_value = arg_count;
uint8_t init_opcode = opline->opcode;
if (opline->opcode == ZEND_INIT_FCALL) {
if (init_opcode == ZEND_INIT_FCALL) {
opline->op1.num = zend_vm_calc_used_stack(arg_count, fbc);
}
@@ -3990,6 +4058,12 @@ static bool zend_compile_call_common(znode *result, zend_ast *args_ast, const ze
false
);
opline = zend_emit_op(result, call_op, NULL, NULL);
if (type == BP_VAR_R || type == BP_VAR_IS) {
if (init_opcode != ZEND_NEW && opline->result_type == IS_VAR) {
opline->result_type = IS_TMP_VAR;
result->op_type = IS_TMP_VAR;
}
}
if (may_have_extra_named_args) {
opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS;
}
@@ -4012,7 +4086,7 @@ static bool zend_compile_function_name(znode *name_node, zend_ast *name_ast) /*
}
/* }}} */
static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast, uint32_t lineno) /* {{{ */
static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast *args_ast, uint32_t lineno, uint32_t type) /* {{{ */
{
if (name_node->op_type == IS_CONST && Z_TYPE(name_node->u.constant) == IS_STRING) {
const char *colon;
@@ -4042,7 +4116,7 @@ static void zend_compile_dynamic_call(znode *result, znode *name_node, zend_ast
zend_emit_op(NULL, ZEND_INIT_DYNAMIC_CALL, NULL, name_node);
}
zend_compile_call_common(result, args_ast, NULL, lineno);
zend_compile_call_common(result, args_ast, NULL, lineno, type);
}
/* }}} */
@@ -4284,7 +4358,7 @@ static void zend_compile_init_user_func(zend_ast *name_ast, uint32_t num_args, z
/* }}} */
/* cufa = call_user_func_array */
static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, zend_string *lcname) /* {{{ */
static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, zend_string *lcname, uint32_t type) /* {{{ */
{
znode arg_node;
zend_op *opline;
@@ -4319,7 +4393,11 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze
zend_compile_expr(&len_node, list->child[2]);
opline = zend_emit_op(NULL, ZEND_SEND_ARRAY, &arg_node, &len_node);
opline->extended_value = Z_LVAL_P(zv);
zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
if (type == BP_VAR_R || type == BP_VAR_IS) {
opline->result_type = IS_TMP_VAR;
result->op_type = IS_TMP_VAR;
}
zend_string_release_ex(name, 0);
return SUCCESS;
}
@@ -4330,6 +4408,10 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze
zend_emit_op(NULL, ZEND_SEND_ARRAY, &arg_node, NULL);
zend_emit_op(NULL, ZEND_CHECK_UNDEF_ARGS, NULL, NULL);
opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
if (type == BP_VAR_R || type == BP_VAR_IS) {
opline->result_type = IS_TMP_VAR;
result->op_type = IS_TMP_VAR;
}
opline->extended_value = ZEND_FCALL_MAY_HAVE_EXTRA_NAMED_PARAMS;
return SUCCESS;
@@ -4337,7 +4419,7 @@ static zend_result zend_compile_func_cufa(znode *result, zend_ast_list *args, ze
/* }}} */
/* cuf = call_user_func */
static zend_result zend_compile_func_cuf(znode *result, const zend_ast_list *args, zend_string *lcname) /* {{{ */
static zend_result zend_compile_func_cuf(znode *result, const zend_ast_list *args, zend_string *lcname, uint32_t type) /* {{{ */
{
uint32_t i;
@@ -4357,13 +4439,17 @@ static zend_result zend_compile_func_cuf(znode *result, const zend_ast_list *arg
opline->op2.num = i;
opline->result.var = EX_NUM_TO_VAR(i - 1);
}
zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
zend_op *opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL);
if (type == BP_VAR_R || type == BP_VAR_IS) {
opline->result_type = IS_TMP_VAR;
result->op_type = IS_TMP_VAR;
}
return SUCCESS;
}
/* }}} */
static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, const zend_function *fbc, uint32_t lineno) /* {{{ */
static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string *name, const zend_function *fbc, uint32_t lineno, uint32_t type) /* {{{ */
{
if (EG(assertions) >= 0) {
znode name_node;
@@ -4398,7 +4484,7 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string
args = (zend_ast_list *)zend_ast_list_add((zend_ast *) args, arg);
}
zend_compile_call_common(result, (zend_ast*)args, fbc, lineno);
zend_compile_call_common(result, (zend_ast*)args, fbc, lineno, type);
opline = &CG(active_op_array)->opcodes[check_op_number];
opline->op2.opline_num = get_next_op_number();
@@ -4649,10 +4735,6 @@ static const zend_frameless_function_info *find_frameless_function_info(const ze
return NULL;
}
if (type != BP_VAR_R) {
return NULL;
}
if (ZEND_USER_CODE(fbc->type)) {
return NULL;
}
@@ -4763,7 +4845,7 @@ static void zend_compile_ns_call(znode *result, const znode *name_node, zend_ast
opline->op2_type = IS_CONST;
opline->op2.constant = name_constants;
opline->result.num = zend_alloc_cache_slot();
zend_compile_call_common(result, args_ast, NULL, lineno);
zend_compile_call_common(result, args_ast, NULL, lineno, type);
/* Compile frameless call. */
if (frameless_function_info) {
@@ -5177,9 +5259,9 @@ static zend_result zend_try_compile_special_func_ex(znode *result, zend_string *
} else if (zend_string_equals_literal(lcname, "ord") && type == BP_VAR_R) {
return zend_compile_func_ord(result, args);
} else if (zend_string_equals_literal(lcname, "call_user_func_array")) {
return zend_compile_func_cufa(result, args, lcname);
return zend_compile_func_cufa(result, args, lcname, type);
} else if (zend_string_equals_literal(lcname, "call_user_func")) {
return zend_compile_func_cuf(result, args, lcname);
return zend_compile_func_cuf(result, args, lcname, type);
} else if (zend_string_equals_literal(lcname, "in_array")) {
return zend_compile_func_in_array(result, args);
} else if (zend_string_equals(lcname, ZSTR_KNOWN(ZEND_STR_COUNT))
@@ -5314,7 +5396,7 @@ static bool zend_compile_parent_property_hook_call(znode *result, const zend_ast
opline->op1.constant = zend_add_literal_string(&property_name);
opline->op2.num = hook_kind;
zend_compile_call_common(result, args_ast, NULL, zend_ast_get_lineno(method_ast));
zend_compile_call_common(result, args_ast, NULL, zend_ast_get_lineno(method_ast), BP_VAR_R);
return true;
}
@@ -5329,7 +5411,7 @@ static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type)
if (name_ast->kind != ZEND_AST_ZVAL || Z_TYPE_P(zend_ast_get_zval(name_ast)) != IS_STRING) {
zend_compile_expr(&name_node, name_ast);
zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno);
zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno, type);
return;
}
@@ -5338,7 +5420,7 @@ static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type)
if (runtime_resolution) {
if (zend_string_equals_literal_ci(zend_ast_get_str(name_ast), "assert")
&& !is_callable_convert) {
zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL, ast->lineno);
zend_compile_assert(result, zend_ast_get_list(args_ast), Z_STR(name_node.u.constant), NULL, ast->lineno, type);
} else {
zend_compile_ns_call(result, &name_node, args_ast, ast->lineno, type);
}
@@ -5355,7 +5437,7 @@ static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type)
/* Special assert() handling should apply independently of compiler flags. */
if (fbc && zend_string_equals_literal(lcname, "assert") && !is_callable_convert) {
zend_compile_assert(result, zend_ast_get_list(args_ast), lcname, fbc, ast->lineno);
zend_compile_assert(result, zend_ast_get_list(args_ast), lcname, fbc, ast->lineno, type);
zend_string_release(lcname);
zval_ptr_dtor(&name_node.u.constant);
return;
@@ -5365,7 +5447,7 @@ static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type)
|| !fbc_is_finalized(fbc)
|| zend_compile_ignore_function(fbc, CG(active_op_array)->filename)) {
zend_string_release_ex(lcname, 0);
zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno);
zend_compile_dynamic_call(result, &name_node, args_ast, ast->lineno, type);
return;
}
@@ -5390,7 +5472,7 @@ static void zend_compile_call(znode *result, const zend_ast *ast, uint32_t type)
Z_EXTRA_P(CT_CONSTANT(opline->op2)) = fbc_bucket - CG(function_table)->arData;
}
zend_compile_call_common(result, args_ast, fbc, ast->lineno);
zend_compile_call_common(result, args_ast, fbc, ast->lineno, type);
}
}
/* }}} */
@@ -5411,7 +5493,7 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type
if (this_guaranteed_exists()) {
obj_node.op_type = IS_UNUSED;
} else {
zend_emit_op(&obj_node, ZEND_FETCH_THIS, NULL, NULL);
zend_emit_op_tmp(&obj_node, ZEND_FETCH_THIS, NULL, NULL);
}
CG(active_op_array)->fn_flags |= ZEND_ACC_USES_THIS;
@@ -5454,7 +5536,7 @@ static void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type
}
}
if (zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast))) {
if (zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast), type)) {
if (short_circuiting_checkpoint != zend_short_circuiting_checkpoint()) {
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot combine nullsafe operator with Closure creation");
@@ -5569,7 +5651,7 @@ static void zend_compile_static_call(znode *result, zend_ast *ast, uint32_t type
}
}
zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast));
zend_compile_call_common(result, args_ast, fbc, zend_ast_get_lineno(method_ast), type);
}
/* }}} */
@@ -5590,7 +5672,7 @@ static void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */
zend_compile_class_ref(&class_node, class_ast, ZEND_FETCH_CLASS_EXCEPTION);
}
opline = zend_emit_op(result, ZEND_NEW, NULL, NULL);
opline = zend_emit_op_tmp(result, ZEND_NEW, NULL, NULL);
zend_set_class_name_op1(opline, &class_node);
@@ -5625,7 +5707,7 @@ static void zend_compile_new(znode *result, zend_ast *ast) /* {{{ */
fbc = ce->constructor;
}
zend_compile_call_common(&ctor_result, args_ast, fbc, ast->lineno);
zend_compile_call_common(&ctor_result, args_ast, fbc, ast->lineno, BP_VAR_R);
zend_do_free(&ctor_result);
}
/* }}} */
@@ -5900,7 +5982,7 @@ static void zend_compile_return(const zend_ast *ast) /* {{{ */
if (!expr_ast) {
expr_node.op_type = IS_CONST;
ZVAL_NULL(&expr_node.u.constant);
} else if (by_ref && zend_is_variable(expr_ast)) {
} else if (by_ref && zend_is_variable_or_call(expr_ast)) {
zend_assert_not_short_circuited(expr_ast);
zend_compile_var(&expr_node, expr_ast, BP_VAR_W, true);
} else {
@@ -6290,7 +6372,8 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
zend_ast *key_ast = ast->child[2];
zend_ast *stmt_ast = ast->child[3];
bool by_ref = value_ast->kind == ZEND_AST_REF;
bool is_variable = zend_is_variable(expr_ast) && zend_can_write_to_variable(expr_ast);
bool is_variable = (zend_is_variable(expr_ast) && zend_can_write_to_variable(expr_ast))
|| zend_is_call(expr_ast);
znode expr_node, reset_node, value_node, key_node;
zend_op *opline;
@@ -6325,6 +6408,10 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
opnum_reset = get_next_op_number();
opline = zend_emit_op(&reset_node, by_ref ? ZEND_FE_RESET_RW : ZEND_FE_RESET_R, &expr_node, NULL);
if (!by_ref) {
opline->result_type = IS_TMP_VAR;
reset_node.op_type = IS_TMP_VAR;
}
zend_begin_loop(ZEND_FE_FREE, &reset_node, false);
@@ -6337,11 +6424,11 @@ static void zend_compile_foreach(zend_ast *ast) /* {{{ */
zend_try_compile_cv(&value_node, value_ast, BP_VAR_R) == SUCCESS) {
SET_NODE(opline->op2, &value_node);
} else {
opline->op2_type = IS_VAR;
opline->op2_type = by_ref ? IS_VAR : IS_TMP_VAR;
opline->op2.var = get_temporary_variable();
GET_NODE(&value_node, opline->op2);
if (value_ast->kind == ZEND_AST_ARRAY) {
zend_compile_list_assign(NULL, value_ast, &value_node, value_ast->attr);
zend_compile_list_assign(NULL, value_ast, &value_node, value_ast->attr, BP_VAR_R);
} else if (by_ref) {
zend_emit_assign_ref_znode(value_ast, &value_node);
} else {
@@ -6679,7 +6766,7 @@ static bool zend_is_pipe_optimizable_callable_name(zend_ast *ast)
return true;
}
static void zend_compile_pipe(znode *result, zend_ast *ast)
static void zend_compile_pipe(znode *result, zend_ast *ast, uint32_t type)
{
zend_ast *operand_ast = ast->child[0];
zend_ast *callable_ast = ast->child[1];
@@ -6734,7 +6821,7 @@ static void zend_compile_pipe(znode *result, zend_ast *ast)
zend_do_extended_stmt(&operand_result);
zend_compile_expr(result, fcall_ast);
zend_compile_var(result, fcall_ast, type, /* by_ref */ false);
}
static void zend_compile_match(znode *result, zend_ast *ast)
@@ -10756,7 +10843,7 @@ static void zend_compile_conditional(znode *result, zend_ast *ast) /* {{{ */
zend_compile_expr(&false_node, false_ast);
opline_qm_assign2 = zend_emit_op(NULL, ZEND_QM_ASSIGN, &false_node, NULL);
opline_qm_assign2 = zend_emit_op_tmp(NULL, ZEND_QM_ASSIGN, &false_node, NULL);
SET_NODE(opline_qm_assign2->result, result);
zend_update_jump_target_to_next(opnum_jmp);
@@ -10932,7 +11019,7 @@ static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
}
if (value_ast) {
if (returns_by_ref && zend_is_variable(value_ast)) {
if (returns_by_ref && zend_is_variable_or_call(value_ast)) {
zend_assert_not_short_circuited(value_ast);
zend_compile_var(&value_node, value_ast, BP_VAR_W, true);
} else {
@@ -10941,7 +11028,7 @@ static void zend_compile_yield(znode *result, zend_ast *ast) /* {{{ */
value_node_ptr = &value_node;
}
opline = zend_emit_op(result, ZEND_YIELD, value_node_ptr, key_node_ptr);
opline = zend_emit_op_tmp(result, ZEND_YIELD, value_node_ptr, key_node_ptr);
if (value_ast && returns_by_ref && zend_is_call(value_ast)) {
opline->extended_value = ZEND_RETURNS_FUNCTION;
@@ -11007,7 +11094,7 @@ static void zend_compile_include_or_eval(znode *result, const zend_ast *ast) /*
zend_do_extended_fcall_begin();
zend_compile_expr(&expr_node, expr_ast);
opline = zend_emit_op(result, ZEND_INCLUDE_OR_EVAL, &expr_node, NULL);
opline = zend_emit_op_tmp(result, ZEND_INCLUDE_OR_EVAL, &expr_node, NULL);
opline->extended_value = ast->attr;
zend_do_extended_fcall_end();
@@ -11989,6 +12076,15 @@ static void zend_compile_stmt(zend_ast *ast) /* {{{ */
case ZEND_AST_CAST_VOID:
zend_compile_void_cast(NULL, ast);
break;
case ZEND_AST_ASSIGN: {
znode result;
zend_compile_assign(&result, ast, /* stmt */ true, BP_VAR_R);
zend_do_free(&result);
return;
}
case ZEND_AST_ASSIGN_REF:
zend_compile_assign_ref(NULL, ast, BP_VAR_R);
return;
default:
{
znode result;
@@ -12009,7 +12105,7 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
CG(zend_lineno) = zend_ast_get_lineno(ast);
if (CG(memoize_mode) != ZEND_MEMOIZE_NONE) {
zend_compile_memoized_expr(result, ast);
zend_compile_memoized_expr(result, ast, BP_VAR_R);
return;
}
@@ -12031,13 +12127,14 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
case ZEND_AST_NULLSAFE_METHOD_CALL:
case ZEND_AST_STATIC_CALL:
case ZEND_AST_PARENT_PROPERTY_HOOK_CALL:
case ZEND_AST_PIPE:
zend_compile_var(result, ast, BP_VAR_R, false);
return;
case ZEND_AST_ASSIGN:
zend_compile_assign(result, ast);
zend_compile_assign(result, ast, /* stmt */ false, BP_VAR_R);
return;
case ZEND_AST_ASSIGN_REF:
zend_compile_assign_ref(result, ast);
zend_compile_assign_ref(result, ast, BP_VAR_R);
return;
case ZEND_AST_NEW:
zend_compile_new(result, ast);
@@ -12136,9 +12233,6 @@ static void zend_compile_expr_inner(znode *result, zend_ast *ast) /* {{{ */
case ZEND_AST_MATCH:
zend_compile_match(result, ast);
return;
case ZEND_AST_PIPE:
zend_compile_pipe(result, ast);
return;
default:
ZEND_ASSERT(0 /* not supported */);
}
@@ -12152,6 +12246,12 @@ static void zend_compile_expr(znode *result, zend_ast *ast)
uint32_t checkpoint = zend_short_circuiting_checkpoint();
zend_compile_expr_inner(result, ast);
zend_short_circuiting_commit(checkpoint, result, ast);
#if ZEND_DEBUG
if (result) {
/* BP_VAR_R is not allowed to produce IS_VAR. */
ZEND_ASSERT(result->op_type != IS_VAR);
}
#endif
}
static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t type, bool by_ref)
@@ -12164,7 +12264,7 @@ static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t ty
case ZEND_AST_METHOD_CALL:
case ZEND_AST_NULLSAFE_METHOD_CALL:
case ZEND_AST_STATIC_CALL:
zend_compile_memoized_expr(result, ast);
zend_compile_memoized_expr(result, ast, BP_VAR_W);
/* This might not actually produce an opcode, e.g. for expressions evaluated at comptime. */
return NULL;
}
@@ -12193,9 +12293,19 @@ static zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t ty
case ZEND_AST_STATIC_CALL:
zend_compile_static_call(result, ast, type);
return NULL;
case ZEND_AST_PIPE:
zend_compile_pipe(result, ast, type);
return NULL;
case ZEND_AST_ZNODE:
*result = *zend_ast_get_znode(ast);
return NULL;
case ZEND_AST_ASSIGN_REF:
zend_compile_assign_ref(result, ast, type);
return NULL;
case ZEND_AST_ASSIGN:
ZEND_ASSERT(ast->child[0]->kind == ZEND_AST_ARRAY && zend_propagate_list_refs(ast->child[0]));
zend_compile_assign(result, ast, false, type);
return NULL;
default:
if (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET) {
zend_error_noreturn(E_COMPILE_ERROR,
@@ -12214,6 +12324,16 @@ static zend_op *zend_compile_var(znode *result, zend_ast *ast, uint32_t type, bo
uint32_t checkpoint = zend_short_circuiting_checkpoint();
zend_op *opcode = zend_compile_var_inner(result, ast, type, by_ref);
zend_short_circuiting_commit(checkpoint, result, ast);
#if ZEND_DEBUG
if (result
&& (type == BP_VAR_R || type == BP_VAR_IS)
/* Don't check memoized result, as it will force BP_VAR_W even for BP_VAR_IS. */
&& CG(memoize_mode) == ZEND_MEMOIZE_NONE
) {
/* BP_VAR_{R,IS} is not allowed to produce IS_VAR. */
ZEND_ASSERT(result->op_type != IS_VAR);
}
#endif
return opcode;
}

View File

@@ -1324,4 +1324,6 @@ ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, const zval *op);
bool zend_try_ct_eval_cast(zval *result, uint32_t type, zval *op1);
bool zend_op_may_elide_result(uint8_t opcode);
#endif /* ZEND_COMPILE_H */

View File

@@ -5938,3 +5938,29 @@ ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, int op_type, const znode
}
return ret;
}
ZEND_API void zend_return_unwrap_ref(zend_execute_data *execute_data, zval *return_value)
{
if (!return_value || !Z_ISREF_P(return_value)) {
return;
}
zend_execute_data *prev_ex = EX(prev_execute_data);
if (!prev_ex || !prev_ex->func || !ZEND_USER_CODE(prev_ex->func->type)) {
return;
}
const zend_op *do_opline = prev_ex->opline;
if (do_opline->result_type != IS_TMP_VAR) {
return;
}
if (do_opline->opcode != ZEND_DO_FCALL
&& do_opline->opcode != ZEND_DO_FCALL_BY_NAME
&& do_opline->opcode != ZEND_DO_ICALL
&& do_opline->opcode != ZEND_DO_UCALL) {
return;
}
zend_unwrap_reference(return_value);
}

View File

@@ -632,6 +632,8 @@ static zend_always_inline void *zend_get_bad_ptr(void)
return NULL;
}
ZEND_API void zend_return_unwrap_ref(zend_execute_data *call, zval *return_value);
END_EXTERN_C()
#endif /* ZEND_EXECUTE_H */

View File

@@ -654,7 +654,9 @@ ZEND_API zend_generator *zend_generator_update_current(zend_generator *generator
} else {
zval_ptr_dtor(&new_root->value);
ZVAL_COPY(&new_root->value, &new_root_parent->value);
ZVAL_COPY(ZEND_CALL_VAR(new_root->execute_data, yield_from->result.var), &new_root_parent->retval);
if (yield_from->result_type != IS_UNUSED) {
ZVAL_COPY(ZEND_CALL_VAR(new_root->execute_data, yield_from->result.var), &new_root_parent->retval);
}
}
}
}

View File

@@ -203,7 +203,7 @@ ZEND_VM_C_LABEL(mul_double):
ZEND_VM_DISPATCH_TO_HELPER(zend_mul_helper, op_1, op1, op_2, op2);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(4, ZEND_DIV, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_COLD_CONSTCONST_HANDLER(4, ZEND_DIV, CONST|TMP|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *op1, *op2;
@@ -357,7 +357,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(7, ZEND_SR, CONST|TMPVARCV, CONST|TMPVARCV)
ZEND_VM_DISPATCH_TO_HELPER(zend_shift_right_helper, op_1, op1, op_2, op2);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMP|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *op1, *op2;
@@ -371,7 +371,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(12, ZEND_POW, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_CONST))
ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMP|CV, CONST|TMP|CV, SPEC(NO_CONST_CONST))
{
USE_OPLINE
zval *op1, *op2;
@@ -448,7 +448,7 @@ ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(NO_CONST_
}
}
ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
@@ -463,7 +463,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(16, ZEND_IS_IDENTICAL, CONST|TMP|VAR|CV, CONST|T
ZEND_VM_SMART_BRANCH(result, 1);
}
ZEND_VM_HANDLER(196, ZEND_CASE_STRICT, TMP|VAR, CONST|TMP|VAR|CV)
ZEND_VM_HANDLER(196, ZEND_CASE_STRICT, TMP, CONST|TMP|CV)
{
USE_OPLINE
zval *op1, *op2;
@@ -477,7 +477,7 @@ ZEND_VM_HANDLER(196, ZEND_CASE_STRICT, TMP|VAR, CONST|TMP|VAR|CV)
ZEND_VM_SMART_BRANCH(result, 1);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV, SPEC(COMMUTATIVE))
ZEND_VM_COLD_CONSTCONST_HANDLER(17, ZEND_IS_NOT_IDENTICAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
@@ -514,7 +514,7 @@ ZEND_VM_HELPER(zend_is_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
ZEND_VM_SMART_BRANCH(ret == 0, 1);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(18, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
ZEND_VM_COLD_CONSTCONST_HANDLER(18, ZEND_IS_EQUAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
@@ -594,7 +594,7 @@ ZEND_VM_HELPER(zend_is_not_equal_helper, ANY, ANY, zval *op_1, zval *op_2)
ZEND_VM_SMART_BRANCH(ret != 0, 1);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(19, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
ZEND_VM_COLD_CONSTCONST_HANDLER(19, ZEND_IS_NOT_EQUAL, CONST|TMP|CV, CONST|TMP|CV, SPEC(SMART_BRANCH,COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
@@ -786,7 +786,7 @@ ZEND_VM_C_LABEL(is_smaller_or_equal_double):
ZEND_VM_DISPATCH_TO_HELPER(zend_is_smaller_or_equal_helper, op_1, op1, op_2, op2);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(170, ZEND_SPACESHIP, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_COLD_CONSTCONST_HANDLER(170, ZEND_SPACESHIP, CONST|TMP|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *op1, *op2;
@@ -917,7 +917,7 @@ ZEND_VM_HOT_NOCONSTCONST_HANDLER(11, ZEND_BW_XOR, CONST|TMPVARCV, CONST|TMPVARCV
ZEND_VM_DISPATCH_TO_HELPER(zend_bw_xor_helper, op_1, op1, op_2, op2);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(15, ZEND_BOOL_XOR, CONST|TMPVAR|CV, CONST|TMPVAR|CV, SPEC(COMMUTATIVE))
ZEND_VM_COLD_CONSTCONST_HANDLER(15, ZEND_BOOL_XOR, CONST|TMP|CV, CONST|TMP|CV, SPEC(COMMUTATIVE))
{
USE_OPLINE
zval *op1, *op2;
@@ -958,7 +958,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(13, ZEND_BW_NOT, CONST|TMPVARCV, ANY)
ZEND_VM_DISPATCH_TO_HELPER(zend_bw_not_helper, op_1, op1);
}
ZEND_VM_COLD_CONST_HANDLER(14, ZEND_BOOL_NOT, CONST|TMPVAR|CV, ANY)
ZEND_VM_COLD_CONST_HANDLER(14, ZEND_BOOL_NOT, CONST|TMP|CV, ANY)
{
USE_OPLINE
zval *val;
@@ -1005,7 +1005,7 @@ ZEND_VM_COLD_HELPER(zend_undefined_function_helper, ANY, ANY)
HANDLE_EXCEPTION();
}
ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, OP)
ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMP|CV, OP)
{
USE_OPLINE
zval *object;
@@ -1097,7 +1097,7 @@ ZEND_VM_C_LABEL(assign_op_object):
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMPVAR) */
/* No specialization for op_types (CONST|TMP|VAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP)
{
/* This helper actually never will receive IS_VAR as second op, and has the same handling for VAR and TMP in the first op, but for interoperability with the other binary_assign_op helpers, it is necessary to "include" it */
@@ -1153,7 +1153,7 @@ ZEND_VM_HANDLER(29, ZEND_ASSIGN_STATIC_PROP_OP, ANY, ANY, OP)
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, OP)
ZEND_VM_HANDLER(27, ZEND_ASSIGN_DIM_OP, VAR|CV, CONST|TMP|UNUSED|NEXT|CV, OP)
{
USE_OPLINE
zval *var_ptr;
@@ -1254,7 +1254,7 @@ ZEND_VM_C_LABEL(assign_dim_op_ret_null):
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP)
ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMP|CV, OP)
{
USE_OPLINE
zval *var_ptr;
@@ -1285,7 +1285,7 @@ ZEND_VM_HANDLER(26, ZEND_ASSIGN_OP, VAR|CV, CONST|TMPVAR|CV, OP)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
USE_OPLINE
zval *object;
@@ -1350,12 +1350,12 @@ ZEND_VM_C_LABEL(pre_incdec_object):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HANDLER(133, ZEND_PRE_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_OBJ);
}
ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
USE_OPLINE
zval *object;
@@ -1418,12 +1418,12 @@ ZEND_VM_C_LABEL(post_incdec_object):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HANDLER(135, ZEND_POST_DEC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_OBJ);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
USE_OPLINE
@@ -1451,13 +1451,13 @@ ZEND_VM_HANDLER(38, ZEND_PRE_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_HANDLER(39, ZEND_PRE_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_PRE_INC_STATIC_PROP);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
USE_OPLINE
@@ -1485,7 +1485,7 @@ ZEND_VM_HANDLER(40, ZEND_POST_INC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_HANDLER(41, ZEND_POST_DEC_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_POST_INC_STATIC_PROP);
@@ -1690,7 +1690,7 @@ ZEND_VM_HOT_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
ZEND_VM_DISPATCH_TO_HELPER(zend_post_dec_helper);
}
ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMP|CV, ANY)
{
USE_OPLINE
zval *z;
@@ -1719,7 +1719,7 @@ ZEND_VM_HANDLER(136, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED, int type)
ZEND_VM_HELPER(zend_fetch_var_address_helper, CONST|TMP|CV, UNUSED, int type)
{
USE_OPLINE
zval *varname;
@@ -1820,22 +1820,22 @@ ZEND_VM_C_LABEL(fetch_this):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(80, ZEND_FETCH_R, CONST|TMP|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_R);
}
ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(83, ZEND_FETCH_W, CONST|TMP|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_W);
}
ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(86, ZEND_FETCH_RW, CONST|TMP|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_RW);
}
ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMP|CV, UNUSED, VAR_FETCH)
{
int fetch_type =
(UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) ?
@@ -1843,17 +1843,17 @@ ZEND_VM_HANDLER(92, ZEND_FETCH_FUNC_ARG, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, fetch_type);
}
ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(95, ZEND_FETCH_UNSET, CONST|TMP|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_UNSET);
}
ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_HANDLER(89, ZEND_FETCH_IS, CONST|TMP|CV, UNUSED, VAR_FETCH)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_var_address_helper, type, BP_VAR_IS);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_INLINE_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)
{
USE_OPLINE
@@ -1888,25 +1888,25 @@ ZEND_VM_C_LABEL(copy_deref):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_HANDLER(173, ZEND_FETCH_STATIC_PROP_R, ANY, CLASS_FETCH, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_R);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_HANDLER(174, ZEND_FETCH_STATIC_PROP_W, ANY, CLASS_FETCH, FETCH_REF|DIM_WRITE|CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_W);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_HANDLER(175, ZEND_FETCH_STATIC_PROP_RW, ANY, CLASS_FETCH, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_RW);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, ANY, CLASS_FETCH, FETCH_REF|CACHE_SLOT)
{
if (UNEXPECTED(ZEND_CALL_INFO(EX(call)) & ZEND_CALL_SEND_ARG_BY_REF)) {
@@ -1916,32 +1916,36 @@ ZEND_VM_HANDLER(177, ZEND_FETCH_STATIC_PROP_FUNC_ARG, ANY, CLASS_FETCH, FETCH_RE
}
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_HANDLER(178, ZEND_FETCH_STATIC_PROP_UNSET, ANY, CLASS_FETCH, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_UNSET);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_HANDLER(176, ZEND_FETCH_STATIC_PROP_IS, ANY, CLASS_FETCH, CACHE_SLOT)
{
ZEND_VM_DISPATCH_TO_HELPER(zend_fetch_static_prop_helper, type, BP_VAR_IS);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_COLD_CONSTCONST_HANDLER(81, ZEND_FETCH_DIM_R, CONST|TMPVAR|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *container, *dim, *value;
SAVE_OPLINE();
container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
}
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE != IS_CONST) {
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
ZEND_VM_C_LABEL(fetch_dim_r_array):
value = zend_fetch_dimension_address_inner(Z_ARRVAL_P(container), dim, OP2_TYPE, BP_VAR_R EXECUTE_DATA_CC);
ZVAL_COPY_DEREF(EX_VAR(opline->result.var), value);
} else if (EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
} else if (OP1_TYPE == IS_CV && EXPECTED(Z_TYPE_P(container) == IS_REFERENCE)) {
container = Z_REFVAL_P(container);
if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) {
ZEND_VM_C_GOTO(fetch_dim_r_array);
@@ -1963,7 +1967,7 @@ ZEND_VM_C_LABEL(fetch_dim_r_slow):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|UNUSED|NEXT|CV)
{
USE_OPLINE
zval *container;
@@ -1978,7 +1982,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|UNUSED|NEXT|CV)
{
USE_OPLINE
zval *container;
@@ -1993,13 +1997,15 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_COLD_CONSTCONST_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_COLD_CONSTCONST_HANDLER(90, ZEND_FETCH_DIM_IS, CONST|TMPVAR|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *container;
SAVE_OPLINE();
container = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_IS);
/* Unlike FETCH_DIM_R, this may receive references through return-by-ref
* calls using ??=, i.e. foo()['bar'] ??= baz. */
zend_fetch_dimension_address_read_IS(container, GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R), OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
FREE_OP2();
FREE_OP1();
@@ -2030,7 +2036,7 @@ ZEND_VM_COLD_HELPER(zend_use_undef_in_read_context_helper, ANY, ANY)
HANDLE_EXCEPTION();
}
ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV)
ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|UNUSED|NEXT|CV)
{
#if !ZEND_VM_SPEC
USE_OPLINE
@@ -2045,11 +2051,17 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, C
if (OP2_TYPE == IS_UNUSED) {
ZEND_VM_DISPATCH_TO_HELPER(zend_use_undef_in_read_context_helper);
}
if (OP1_TYPE & IS_VAR) {
zval *op1 = EX_VAR(opline->op1.var);
if (Z_TYPE_P(op1) == IS_REFERENCE) {
zend_unwrap_reference(op1);
}
}
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_DIM_R);
}
}
ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *container;
@@ -2064,7 +2076,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
USE_OPLINE
zval *container;
@@ -2072,11 +2084,15 @@ ZEND_VM_HOT_OBJ_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMPVAR|UNUSED|THIS|CV, CONST
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR_UNDEF(BP_VAR_R);
if (OP1_TYPE & (IS_VAR|IS_TMP_VAR)) {
/* Handler accepts VAR only for FUNC_ARG, which will unwrap before dispatching. */
ZEND_ASSERT(Z_TYPE_P(container) != IS_REFERENCE);
}
if (OP1_TYPE == IS_CONST ||
(OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
do {
if ((OP1_TYPE & (IS_VAR|IS_CV)) && Z_ISREF_P(container)) {
if ((OP1_TYPE & IS_CV) && Z_ISREF_P(container)) {
container = Z_REFVAL_P(container);
if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
break;
@@ -2233,7 +2249,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_finish):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|DIM_WRITE|CACHE_SLOT)
ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMP|CV, FETCH_REF|DIM_WRITE|CACHE_SLOT)
{
USE_OPLINE
zval *property, *container, *result;
@@ -2254,7 +2270,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
USE_OPLINE
zval *property, *container, *result;
@@ -2271,7 +2287,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACH
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
USE_OPLINE
zval *container;
@@ -2279,6 +2295,8 @@ ZEND_VM_COLD_CONST_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMPVAR|UNUSED|THIS|CV, C
SAVE_OPLINE();
container = GET_OP1_OBJ_ZVAL_PTR(BP_VAR_IS);
/* Unlike FETCH_OBJ_R, this may receive references through return-by-ref
* calls using ??=, i.e. foo()->bar ??= baz. */
if (OP1_TYPE == IS_CONST ||
(OP1_TYPE != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT))) {
@@ -2392,7 +2410,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_finish):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH_REF|CACHE_SLOT)
ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THIS|CV, CONST|TMP|CV, FETCH_REF|CACHE_SLOT)
{
#if !ZEND_VM_SPEC
USE_OPLINE
@@ -2405,11 +2423,17 @@ ZEND_VM_COLD_CONST_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|THI
}
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_W);
} else {
if (OP1_TYPE == IS_VAR) {
zval *op1 = EX_VAR(opline->op1.var);
if (Z_TYPE_P(op1) == IS_REFERENCE) {
zend_unwrap_reference(op1);
}
}
ZEND_VM_DISPATCH_TO_HANDLER(ZEND_FETCH_OBJ_R);
}
}
ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
USE_OPLINE
zval *container, *property, *result;
@@ -2426,7 +2450,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMP|CV)
{
USE_OPLINE
zval *container;
@@ -2438,7 +2462,7 @@ ZEND_VM_HANDLER(98, ZEND_FETCH_LIST_R, CONST|TMPVARCV, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMP|CV)
{
USE_OPLINE
zval *container, *dim;
@@ -2461,7 +2485,7 @@ ZEND_VM_HANDLER(155, ZEND_FETCH_LIST_W, VAR, CONST|TMPVAR|CV)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
ZEND_VM_HANDLER(24, ZEND_ASSIGN_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|CV))
{
USE_OPLINE
zval *object, *value, tmp;
@@ -2614,8 +2638,8 @@ ZEND_VM_C_LABEL(exit_assign_obj):
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|VAR|CV))
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=CONST|TMP|CV))
{
USE_OPLINE
zval *prop, *value;
@@ -2652,7 +2676,7 @@ ZEND_VM_HANDLER(25, ZEND_ASSIGN_STATIC_PROP, ANY, ANY, CACHE_SLOT, SPEC(OP_DATA=
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HANDLER(23, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|VAR|CV))
ZEND_VM_HANDLER(23, ZEND_ASSIGN_DIM, VAR|CV, CONST|TMP|UNUSED|NEXT|CV, SPEC(OP_DATA=CONST|TMP|CV))
{
USE_OPLINE
zval *object_ptr, *orig_object_ptr;
@@ -2805,7 +2829,7 @@ ZEND_VM_C_LABEL(assign_dim_error):
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV, SPEC(RETVAL))
ZEND_VM_HANDLER(22, ZEND_ASSIGN, VAR|CV, CONST|TMP|CV, SPEC(RETVAL))
{
USE_OPLINE
zval *value;
@@ -2873,7 +2897,7 @@ ZEND_VM_HANDLER(30, ZEND_ASSIGN_REF, VAR|CV, VAR|CV, SRC)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT|SRC, SPEC(OP_DATA=VAR|CV))
ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT|SRC, SPEC(OP_DATA=VAR|CV))
{
USE_OPLINE
zval *property, *container, *value_ptr;
@@ -2909,7 +2933,7 @@ ZEND_VM_HANDLER(32, ZEND_ASSIGN_OBJ_REF, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CA
ZEND_VM_NEXT_OPCODE_EX(1, 2);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CONST|TMP) */
ZEND_VM_HANDLER(33, ZEND_ASSIGN_STATIC_PROP_REF, ANY, ANY, CACHE_SLOT|SRC)
{
USE_OPLINE
@@ -3107,7 +3131,7 @@ ZEND_VM_HOT_HANDLER(42, ZEND_JMP, JMP_ADDR, ANY)
ZEND_VM_JMP_EX(OP_JMP_ADDR(opline, opline->op1), 0);
}
ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *val;
@@ -3141,7 +3165,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_JMP(opline);
}
ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *val;
@@ -3175,7 +3199,7 @@ ZEND_VM_HOT_NOCONST_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_JMP(opline);
}
ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *val;
@@ -3211,7 +3235,7 @@ ZEND_VM_COLD_CONST_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_JMP(opline);
}
ZEND_VM_COLD_CONST_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, JMP_ADDR)
ZEND_VM_COLD_CONST_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *val;
@@ -3280,7 +3304,7 @@ ZEND_VM_HOT_HANDLER(127, ZEND_FE_FREE, TMPVAR, LOOP_END)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMP|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *op1, *op2;
@@ -3405,7 +3429,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(53, ZEND_FAST_CONCAT, CONST|TMPVAR|CV, CONST|TMP
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM)
ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMP|CV, NUM)
{
USE_OPLINE
zend_string **rope;
@@ -3440,7 +3464,7 @@ ZEND_VM_HANDLER(54, ZEND_ROPE_INIT, UNUSED, CONST|TMPVAR|CV, NUM)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM)
ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMP|CV, NUM)
{
USE_OPLINE
zend_string **rope;
@@ -3475,7 +3499,7 @@ ZEND_VM_HANDLER(55, ZEND_ROPE_ADD, TMP, CONST|TMPVAR|CV, NUM)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMP|CV, NUM)
{
USE_OPLINE
zend_string **rope;
@@ -3535,7 +3559,7 @@ ZEND_VM_HANDLER(56, ZEND_ROPE_END, TMP, CONST|TMPVAR|CV, NUM)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMPVAR|UNUSED|CV, CACHE_SLOT)
ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, UNUSED|CLASS_FETCH, CONST|TMP|UNUSED|CV, CACHE_SLOT)
{
zval *class_name;
USE_OPLINE
@@ -3578,7 +3602,7 @@ ZEND_VM_C_LABEL(try_class_name):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, NUM|CACHE_SLOT)
ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMP|UNUSED|THIS|CV, CONST|TMP|CV, NUM|CACHE_SLOT)
{
USE_OPLINE
zval *function_name;
@@ -3733,7 +3757,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMPVAR|UNUSED|CONSTRUCTOR|CV, NUM|CACHE_SLOT)
ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR, CONST|TMP|UNUSED|CONSTRUCTOR|CV, NUM|CACHE_SLOT)
{
USE_OPLINE
zval *function_name;
@@ -3894,7 +3918,7 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMPVAR|CV, NUM)
ZEND_VM_HANDLER(128, ZEND_INIT_DYNAMIC_CALL, ANY, CONST|TMP|CV, NUM)
{
USE_OPLINE
zval *function_name;
@@ -3947,7 +3971,7 @@ ZEND_VM_C_LABEL(try_function_name):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM)
ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMP|CV, NUM)
{
USE_OPLINE
zval *function_name;
@@ -4263,6 +4287,7 @@ ZEND_VM_HOT_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL,OBSERVER))
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
zend_verify_internal_func_info(call->func, ret);
}
ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
#endif
ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
ZEND_VM_FCALL_INTERRUPT_CHECK(call);
@@ -4391,6 +4416,7 @@ ZEND_VM_HOT_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL,OBSERVER))
? Z_ISREF_P(ret) : !Z_ISREF_P(ret));
zend_verify_internal_func_info(call->func, ret);
}
ZEND_ASSERT(opline->result_type != IS_TMP_VAR || !Z_ISREF_P(ret));
#endif
ZEND_OBSERVER_FCALL_END(call, EG(exception) ? NULL : ret);
ZEND_VM_FCALL_INTERRUPT_CHECK(call);
@@ -4500,7 +4526,7 @@ ZEND_VM_COLD_HANDLER(201, ZEND_VERIFY_NEVER_TYPE, UNUSED, UNUSED)
HANDLE_EXCEPTION();
}
ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER))
ZEND_VM_INLINE_HANDLER(62, ZEND_RETURN, CONST|TMP|CV, ANY, SPEC(OBSERVER))
{
USE_OPLINE
zval *retval_ptr;
@@ -4641,6 +4667,9 @@ ZEND_VM_COLD_CONST_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY, SRC,
ZEND_OBSERVER_FCALL_END(execute_data, return_value);
ZEND_OBSERVER_FREE_RETVAL();
zend_return_unwrap_ref(execute_data, return_value);
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
@@ -4769,7 +4798,7 @@ ZEND_VM_HANDLER(161, ZEND_GENERATOR_RETURN, CONST|TMP|VAR|CV, ANY, SPEC(OBSERVER
ZEND_VM_RETURN();
}
ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMPVAR|CV, ANY)
ZEND_VM_COLD_CONST_HANDLER(108, ZEND_THROW, CONST|TMP|CV, ANY)
{
USE_OPLINE
zval *value;
@@ -5624,7 +5653,7 @@ ZEND_VM_C_LABEL(send_array):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(120, ZEND_SEND_USER, CONST|TMP|VAR|CV, NUM)
ZEND_VM_HANDLER(120, ZEND_SEND_USER, CONST|TMP|CV, NUM)
{
USE_OPLINE
zval *arg, *param;
@@ -5834,7 +5863,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, NUM, UNUSED)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_COLD_CONST_HANDLER(52, ZEND_BOOL, CONST|TMPVAR|CV, ANY)
ZEND_VM_COLD_CONST_HANDLER(52, ZEND_BOOL, CONST|TMP|CV, ANY)
{
USE_OPLINE
zval *val;
@@ -5879,7 +5908,7 @@ ZEND_VM_HELPER(zend_case_helper, ANY, ANY, zval *op_1, zval *op_2)
ZEND_VM_SMART_BRANCH(ret == 0, 1);
}
ZEND_VM_HANDLER(48, ZEND_CASE, TMPVAR, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(48, ZEND_CASE, TMP, CONST|TMP|CV)
{
USE_OPLINE
zval *op1, *op2;
@@ -5999,7 +6028,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
ZEND_VM_COLD_CONST_HANDLER(110, ZEND_CLONE, CONST|TMP|UNUSED|THIS|CV, ANY)
{
USE_OPLINE
zval *obj;
@@ -6213,7 +6242,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMPVAR|UNUSED|NEXT|CV, REF)
ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|UNUSED|NEXT|CV, REF)
{
USE_OPLINE
zval *expr_ptr, new_expr;
@@ -6462,7 +6491,7 @@ ZEND_VM_C_LABEL(add_unpack_again):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|UNUSED|NEXT|CV, ARRAY_INIT|REF)
ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|UNUSED|NEXT|CV, ARRAY_INIT|REF)
{
zval *array;
uint32_t size;
@@ -6484,7 +6513,7 @@ ZEND_VM_HANDLER(71, ZEND_INIT_ARRAY, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|UNUSE
}
}
ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|CV, ANY, TYPE)
{
USE_OPLINE
zval *expr;
@@ -6533,7 +6562,7 @@ ZEND_VM_COLD_CONST_HANDLER(51, ZEND_CAST, CONST|TMP|VAR|CV, ANY, TYPE)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL, SPEC(OBSERVER))
ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|CV, ANY, EVAL, SPEC(OBSERVER))
{
USE_OPLINE
zend_op_array *new_op_array;
@@ -6671,7 +6700,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_COLD_HANDLER(179, ZEND_UNSET_STATIC_PROP, ANY, ANY, CACHE_SLOT)
{
USE_OPLINE
@@ -6724,7 +6753,7 @@ ZEND_VM_COLD_HANDLER(179, ZEND_UNSET_STATIC_PROP, ANY, ANY, CACHE_SLOT)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|CV, CONST|TMPVAR|CV)
ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|CV, CONST|TMP|CV)
{
USE_OPLINE
zval *container;
@@ -6826,7 +6855,7 @@ ZEND_VM_C_LABEL(num_index_dim):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_SLOT)
ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMP|CV, CACHE_SLOT)
{
USE_OPLINE
zval *container;
@@ -6871,7 +6900,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACHE_S
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_HANDLER(77, ZEND_FE_RESET_R, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *array_ptr, *result;
@@ -7165,7 +7194,7 @@ ZEND_VM_C_LABEL(fe_fetch_r_exit):
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HOT_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
ZEND_VM_HOT_HANDLER(78, ZEND_FE_FETCH_R, TMP, ANY, JMP_ADDR)
{
USE_OPLINE
zval *array;
@@ -7234,6 +7263,10 @@ ZEND_VM_HOT_HANDLER(78, ZEND_FE_FETCH_R, VAR, ANY, JMP_ADDR)
zend_assign_to_variable(variable_ptr, value, IS_CV, EX_USES_STRICT_TYPES());
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
} else {
if (UNEXPECTED(Z_ISREF_P(value))) {
value = Z_REFVAL_P(value);
value_type = Z_TYPE_INFO_P(value);
}
zval *res = EX_VAR(opline->op2.var);
zend_refcounted *gc = Z_COUNTED_P(value);
@@ -7470,7 +7503,7 @@ ZEND_VM_HOT_HANDLER(154, ZEND_ISSET_ISEMPTY_CV, CV, UNUSED, ISSET, SPEC(ISSET))
}
}
ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|ISSET)
ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|CV, UNUSED, VAR_FETCH|ISSET)
{
USE_OPLINE
zval *value;
@@ -7514,7 +7547,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED, VAR_FETCH|
ZEND_VM_SMART_BRANCH(result, true);
}
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR) */
/* No specialization for op_types (CONST|TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|TMP) */
ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, ANY, CLASS_FETCH, ISSET|CACHE_SLOT)
{
USE_OPLINE
@@ -7535,7 +7568,7 @@ ZEND_VM_HANDLER(180, ZEND_ISSET_ISEMPTY_STATIC_PROP, ANY, CLASS_FETCH, ISSET|CAC
ZEND_VM_SMART_BRANCH(result, 1);
}
ZEND_VM_COLD_CONSTCONST_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMPVAR|CV, CONST|TMPVAR|CV, ISSET)
ZEND_VM_COLD_CONSTCONST_HANDLER(115, ZEND_ISSET_ISEMPTY_DIM_OBJ, CONST|TMP|CV, CONST|TMP|CV, ISSET)
{
USE_OPLINE
zval *container;
@@ -7614,7 +7647,7 @@ ZEND_VM_C_LABEL(isset_dim_obj_exit):
ZEND_VM_SMART_BRANCH(result, 1);
}
ZEND_VM_COLD_CONST_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, ISSET|CACHE_SLOT)
ZEND_VM_COLD_CONST_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMP|UNUSED|THIS|CV, CONST|TMP|CV, ISSET|CACHE_SLOT)
{
USE_OPLINE
zval *container;
@@ -7664,7 +7697,7 @@ ZEND_VM_C_LABEL(isset_object_finish):
ZEND_VM_SMART_BRANCH(result, 1);
}
ZEND_VM_HANDLER(194, ZEND_ARRAY_KEY_EXISTS, CV|TMPVAR|CONST, CV|TMPVAR|CONST)
ZEND_VM_HANDLER(194, ZEND_ARRAY_KEY_EXISTS, CV|TMP|CONST, CV|TMP|CONST)
{
USE_OPLINE
@@ -7742,7 +7775,7 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TMP, ANY)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *value;
@@ -7789,7 +7822,7 @@ ZEND_VM_COLD_CONST_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *value;
@@ -7830,7 +7863,7 @@ ZEND_VM_COLD_CONST_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMP|VAR|CV, JMP_ADDR)
ZEND_VM_HOT_NOCONST_HANDLER(198, ZEND_JMP_NULL, CONST|TMP|CV, JMP_ADDR)
{
USE_OPLINE
zval *val, *result;
@@ -8030,7 +8063,7 @@ ZEND_VM_HANDLER(105, ZEND_TICKS, ANY, ANY, NUM)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMPVAR|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT)
ZEND_VM_HANDLER(138, ZEND_INSTANCEOF, TMP|CV, UNUSED|CLASS_FETCH|CONST|VAR, CACHE_SLOT)
{
USE_OPLINE
zval *expr;
@@ -8386,7 +8419,7 @@ ZEND_VM_COLD_HELPER(zend_yield_in_closed_generator_helper, ANY, ANY)
HANDLE_EXCEPTION();
}
ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|CV|UNUSED, SRC)
ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|CV|UNUSED, SRC)
{
USE_OPLINE
@@ -8507,7 +8540,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMPVAR|CV|UNUSED
ZEND_VM_RETURN();
}
ZEND_VM_HANDLER(166, ZEND_YIELD_FROM, CONST|TMPVAR|CV, ANY)
ZEND_VM_HANDLER(166, ZEND_YIELD_FROM, CONST|TMP|CV, ANY)
{
USE_OPLINE
zend_generator *generator = zend_get_running_generator(EXECUTE_DATA_C);
@@ -8748,7 +8781,7 @@ ZEND_VM_C_LABEL(check_indirect):
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMP|CV, ANY)
{
USE_OPLINE
zval *value;
@@ -8810,7 +8843,7 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMPVAR|CV, ANY, TYPE_MASK)
ZEND_VM_HOT_NOCONST_HANDLER(123, ZEND_TYPE_CHECK, CONST|TMP|CV, ANY, TYPE_MASK)
{
USE_OPLINE
zval *value;
@@ -8916,7 +8949,7 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR)
}
}
ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, CV|TMPVAR|UNUSED|CLASS_FETCH, ANY)
ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, CV|TMP|UNUSED|CLASS_FETCH, ANY)
{
uint32_t fetch_type;
zend_class_entry *called_scope, *scope;
@@ -9429,7 +9462,7 @@ ZEND_VM_COLD_CONST_HANDLER(197, ZEND_MATCH_ERROR, CONST|TMPVARCV, UNUSED)
HANDLE_EXCEPTION();
}
ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM)
ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|CV, CONST, NUM)
{
USE_OPLINE
zval *op1;
@@ -9501,7 +9534,7 @@ ZEND_VM_COLD_CONSTCONST_HANDLER(189, ZEND_IN_ARRAY, CONST|TMP|VAR|CV, CONST, NUM
ZEND_VM_SMART_BRANCH(0, 1);
}
ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMP|CV, UNUSED)
{
USE_OPLINE
zval *op1;
@@ -9556,7 +9589,7 @@ ZEND_VM_COLD_CONST_HANDLER(190, ZEND_COUNT, CONST|TMPVAR|CV, UNUSED)
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
}
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_COUNT, (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY, ZEND_COUNT_ARRAY, CV|TMPVAR, UNUSED)
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_COUNT, (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_BE_REF)) == MAY_BE_ARRAY, ZEND_COUNT_ARRAY, CV|TMP, UNUSED)
{
USE_OPLINE
zend_array *ht = Z_ARRVAL_P(GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R));
@@ -9571,7 +9604,7 @@ ZEND_VM_TYPE_SPEC_HANDLER(ZEND_COUNT, (op1_info & (MAY_BE_ANY|MAY_BE_UNDEF|MAY_B
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONST_HANDLER(191, ZEND_GET_CLASS, UNUSED|CONST|TMPVAR|CV, UNUSED)
ZEND_VM_COLD_CONST_HANDLER(191, ZEND_GET_CLASS, UNUSED|CONST|TMP|CV, UNUSED)
{
USE_OPLINE
@@ -9632,7 +9665,7 @@ ZEND_VM_HANDLER(192, ZEND_GET_CALLED_CLASS, UNUSED, UNUSED)
ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_COLD_CONST_HANDLER(193, ZEND_GET_TYPE, CONST|TMP|VAR|CV, UNUSED)
ZEND_VM_COLD_CONST_HANDLER(193, ZEND_GET_TYPE, CONST|TMP|CV, UNUSED)
{
USE_OPLINE
zval *op1;

31503
Zend/zend_vm_execute.h generated

File diff suppressed because it is too large Load Diff

1764
Zend/zend_vm_handlers.h generated

File diff suppressed because it is too large Load Diff

146
Zend/zend_vm_opcodes.c generated
View File

@@ -242,35 +242,35 @@ static uint32_t zend_vm_opcodes_flags[212] = {
0x00000b0b,
0x00000b0b,
0x80000b0b,
0x00000707,
0x00000303,
0x00000b0b,
0x00000b0b,
0x00000b0b,
0x40000707,
0x40000303,
0x80000b0b,
0x80000b0b,
0x80000b0b,
0x00000707,
0x00000303,
0x0000000b,
0x00000007,
0x80000707,
0x00000003,
0x80000303,
0x80000303,
0x80000303,
0x80000303,
0x80000303,
0x80000707,
0x80000707,
0x00000b0b,
0x00000b0b,
0x00000301,
0x00006701,
0x00040751,
0x00006301,
0x00040351,
0x00040000,
0x04000701,
0x04006701,
0x04000751,
0x04000301,
0x04006301,
0x04000351,
0x04000000,
0x0b000101,
0x00000003,
0x0b040751,
0x0b040351,
0x0b040000,
0x00000001,
0x00000001,
@@ -281,20 +281,20 @@ static uint32_t zend_vm_opcodes_flags[212] = {
0x00040000,
0x00040000,
0x00000020,
0x00002007,
0x00002007,
0x00002003,
0x00002003,
0x00000000,
0x00002007,
0x00002007,
0x00000705,
0x00002003,
0x00002003,
0x00000301,
0x00000101,
0x00001301,
0x07000003,
0x00000007,
0x00000707,
0x01000701,
0x01000701,
0x01000701,
0x00000003,
0x00000303,
0x01000301,
0x01000301,
0x01000301,
0x00000000,
0x00000001,
0x01040300,
@@ -309,34 +309,34 @@ static uint32_t zend_vm_opcodes_flags[212] = {
0x0100a173,
0x01040300,
0x00004005,
0x00186703,
0x00106703,
0x08000007,
0x00186303,
0x00106303,
0x08000003,
0x00010107,
0x00000701,
0x00040751,
0x00000301,
0x00040351,
0x00002003,
0x03000001,
0x00000000,
0x00010107,
0x00000707,
0x00040757,
0x00010107,
0x00006701,
0x00640751,
0x00010107,
0x00006701,
0x00040751,
0x00010107,
0x00000707,
0x00040757,
0x00010107,
0x00006703,
0x00240753,
0x00010107,
0x00000701,
0x00040751,
0x0000070b,
0x00010103,
0x00000307,
0x00040357,
0x00010103,
0x00006301,
0x00640351,
0x00010103,
0x00006301,
0x00040351,
0x00010103,
0x00000307,
0x00040357,
0x00010103,
0x00006303,
0x00240353,
0x00010103,
0x00000301,
0x00040351,
0x0000030b,
0x00040391,
0x00001301,
0x00000000,
@@ -346,37 +346,37 @@ static uint32_t zend_vm_opcodes_flags[212] = {
0x01000000,
0x00001301,
0x02042003,
0x00000007,
0x00040771,
0x00000057,
0x00000003,
0x00040371,
0x00000053,
0x0b000003,
0x01040757,
0x01048773,
0x00030107,
0x00020707,
0x01040353,
0x01048373,
0x00030103,
0x00020303,
0x00001303,
0x00001301,
0x01000703,
0x01000303,
0x01000000,
0x00001003,
0x00000007,
0x00000003,
0x00040003,
0x09000007,
0x09000003,
0x00000103,
0x00002003,
0x03000001,
0x00004005,
0x01000700,
0x01000300,
0x00000000,
0x00000000,
0x00000000,
0x00040751,
0x00040751,
0x00040751,
0x00040751,
0x00000007,
0x00040351,
0x00040351,
0x00040351,
0x00040351,
0x00000003,
0x00000000,
0x00047305,
0x00047301,
0x00000000,
0x00000101,
0x00001000,
@@ -386,29 +386,29 @@ static uint32_t zend_vm_opcodes_flags[212] = {
0x00000303,
0x00040000,
0x00000000,
0x00060757,
0x00060353,
0x00000000,
0x00000000,
0x00002000,
0x00002003,
0x00000101,
0x00020101,
0x00000701,
0x00000301,
0x00000101,
0x00000075,
0x00000071,
0x00000000,
0x00000000,
0x0b000703,
0x0b000303,
0x00000003,
0x00000020,
0x00003000,
0x00000110,
0x00000000,
0x00000007,
0x00000003,
0x00000105,
0x00040301,
0x00002003,
0x00000707,
0x00000303,
0x00000101,
0x00000103,
0x00047000,
@@ -428,11 +428,11 @@ static uint32_t zend_vm_opcodes_flags[212] = {
0x0300030b,
0x0300030b,
0x01000303,
0x00000107,
0x00000107,
0x00000103,
0x00000103,
0x00000101,
0x00000103,
0x00000707,
0x00000303,
0x0300030b,
0x00000301,
0x0000010b,

View File

@@ -7,7 +7,8 @@ mbstring
$a = [];
$b = [];
$a[] = $b[] = &$a;
$b[] = &$a;
$a[] = &$b;
var_dump(mb_convert_variables('utf-8', 'utf-8', $a));
$c = [];

View File

@@ -28,16 +28,16 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL int(1) 1
0002 SEND_VAL int(10) 2
0003 V2 = DO_ICALL
0004 ASSIGN CV0($array) V2
0003 T2 = DO_ICALL
0004 ASSIGN CV0($array) T2
0005 TYPE_ASSERT 131079 string("array_map") CV0($array)
0006 T2 = INIT_ARRAY 0 (packed) NEXT
0007 V3 = FE_RESET_R CV0($array) 0014
0008 T5 = FE_FETCH_R V3 T4 0014
0009 INIT_FCALL 1 %d string("plus1")
0010 SEND_VAL T4 1
0011 V4 = DO_UCALL
0012 T2 = ADD_ARRAY_ELEMENT V4 T5
0011 T4 = DO_UCALL
0012 T2 = ADD_ARRAY_ELEMENT T4 T5
0013 JMP 0008
0014 FE_FREE V3
0015 ASSIGN CV1($foo) T2

View File

@@ -31,19 +31,19 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL int(1) 1
0002 SEND_VAL int(10) 2
0003 V2 = DO_ICALL
0004 ASSIGN CV0($array) V2
0005 V5 = NEW 1 string("ArrayIterator")
0003 T2 = DO_ICALL
0004 ASSIGN CV0($array) T2
0005 T5 = NEW 1 string("ArrayIterator")
0006 SEND_VAR%S CV0($array) 1
0007 DO_FCALL
0008 TYPE_ASSERT 131079 string("array_map") V5
0008 TYPE_ASSERT 131079 string("array_map") T5
0009 T2 = INIT_ARRAY 0 (packed) NEXT
0010 V3 = FE_RESET_R V5 0017
0010 V3 = FE_RESET_R T5 0017
0011 T5 = FE_FETCH_R V3 T4 0017
0012 INIT_FCALL 1 %d string("plus1")
0013 SEND_VAL T4 1
0014 V4 = DO_UCALL
0015 T2 = ADD_ARRAY_ELEMENT V4 T5
0014 T4 = DO_UCALL
0015 T2 = ADD_ARRAY_ELEMENT T4 T5
0016 JMP 0011
0017 FE_FREE V3
0018 ASSIGN CV1($foo) T2

View File

@@ -29,8 +29,8 @@ $_main:
0003 T4 = FE_FETCH_R V2 T3 0009
0004 INIT_FCALL 1 %d string("plus1")
0005 SEND_VAL T3 1
0006 V3 = DO_UCALL
0007 T1 = ADD_ARRAY_ELEMENT V3 T4
0006 T3 = DO_UCALL
0007 T1 = ADD_ARRAY_ELEMENT T3 T4
0008 JMP 0003
0009 FE_FREE V2
0010 ASSIGN CV0($foo) T1

View File

@@ -26,16 +26,16 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL int(1) 1
0002 SEND_VAL int(10) 2
0003 V1 = DO_ICALL
0004 ASSIGN CV0($array) V1
0003 T1 = DO_ICALL
0004 ASSIGN CV0($array) T1
0005 TYPE_ASSERT 131079 string("array_map") CV0($array)
0006 T1 = INIT_ARRAY 0 (packed) NEXT
0007 V2 = FE_RESET_R CV0($array) 0014
0008 T4 = FE_FETCH_R V2 T3 0014
0009 INIT_FCALL 1 %d string("stdclass")
0010 SEND_VAL T3 1
0011 V3 = DO_UCALL
0012 T1 = ADD_ARRAY_ELEMENT V3 T4
0011 T3 = DO_UCALL
0012 T1 = ADD_ARRAY_ELEMENT T3 T4
0013 JMP 0008
0014 FE_FREE V2
0015 FREE T1
@@ -50,8 +50,8 @@ stdClass:
; (lines=3, args=0, vars=0, tmps=%d)
; (after optimizer)
; %s
0000 V0 = NEW 0 string("stdClass")
0000 T0 = NEW 0 string("stdClass")
0001 DO_FCALL
0002 RETURN V0
0002 RETURN T0
LIVE RANGES:
0: 0001 - 0002 (new)

View File

@@ -30,16 +30,16 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL int(1) 1
0002 SEND_VAL int(10) 2
0003 V2 = DO_ICALL
0004 ASSIGN CV0($array) V2
0003 T2 = DO_ICALL
0004 ASSIGN CV0($array) T2
0005 TYPE_ASSERT 131079 string("array_map") CV0($array)
0006 T2 = INIT_ARRAY 0 (packed) NEXT
0007 V3 = FE_RESET_R CV0($array) 0014
0008 T5 = FE_FETCH_R V3 T4 0014
0009 INIT_STATIC_METHOD_CALL 1 string("Adder") string("plus1")
0010 SEND_VAL T4 1
0011 V4 = DO_UCALL
0012 T2 = ADD_ARRAY_ELEMENT V4 T5
0011 T4 = DO_UCALL
0012 T2 = ADD_ARRAY_ELEMENT T4 T5
0013 JMP 0008
0014 FE_FREE V3
0015 ASSIGN CV1($foo) T2

View File

@@ -29,8 +29,8 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL int(1) 1
0002 SEND_VAL int(10) 2
0003 V3 = DO_ICALL
0004 ASSIGN CV0($array) V3
0003 T3 = DO_ICALL
0004 ASSIGN CV0($array) T3
0005 ASSIGN CV1($plus1) string("plus1")
0006 TYPE_ASSERT 131079 string("array_map") CV0($array)
0007 T3 = INIT_ARRAY 0 (packed) NEXT
@@ -38,8 +38,8 @@ $_main:
0009 T6 = FE_FETCH_R V4 T5 0015
0010 INIT_DYNAMIC_CALL 1 CV1($plus1)
0011 SEND_VAL_EX T5 1
0012 V5 = DO_FCALL
0013 T3 = ADD_ARRAY_ELEMENT V5 T6
0012 T5 = DO_FCALL
0013 T3 = ADD_ARRAY_ELEMENT T5 T6
0014 JMP 0009
0015 FE_FREE V4
0016 ASSIGN CV2($foo) T3

View File

@@ -39,9 +39,9 @@ $_main:
; (lines=10, args=0, vars=1, tmps=%d)
; (after optimizer)
; %sdump_property_hooks.php:1-22
0000 V1 = NEW 0 string("A")
0000 T1 = NEW 0 string("A")
0001 DO_FCALL
0002 ASSIGN CV0($a) V1
0002 ASSIGN CV0($a) T1
0003 INIT_FCALL 1 %d string("var_dump")
0004 T1 = FETCH_OBJ_R CV0($a) string("prop")
0005 SEND_VAL T1 1

View File

@@ -0,0 +1,23 @@
--TEST--
Broken live-range calculation with QM_ASSIGN optimization
--EXTENSIONS--
opcache
--INI--
opcache.enable=1
opcache.enable_cli=1
--FILE--
<?php
function test($cond) {
$caller = $cond ? new \ReflectionMethod('non', 'existent') : null;
}
try {
test(true);
} catch (Throwable $e) {
echo $e::class, $e->getMessage(), "\n";
}
?>
--EXPECT--
ReflectionExceptionClass "non" does not exist

View File

@@ -34,17 +34,17 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL string("a") 1
0002 SEND_VAL string("i") 2
0003 V2 = DO_ICALL
0004 V1 = FE_RESET_R V2 0013
0005 FE_FETCH_R V1 CV0($char) 0013
0003 T2 = DO_ICALL
0004 T1 = FE_RESET_R T2 0013
0005 FE_FETCH_R T1 CV0($char) 0013
0006 INIT_FCALL 1 %d string("var_dump")
0007 INIT_FCALL 1 %d string("test")
0008 SEND_VAR CV0($char) 1
0009 V2 = DO_UCALL
0010 SEND_VAR V2 1
0009 T2 = DO_UCALL
0010 SEND_VAL T2 1
0011 DO_ICALL
0012 JMP 0005
0013 FE_FREE V1
0013 FE_FREE T1
0014 RETURN int(1)
LIVE RANGES:
1: 0005 - 0013 (loop)

View File

@@ -35,17 +35,17 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL int(0) 1
0002 SEND_VAL int(10) 2
0003 V2 = DO_ICALL
0004 V1 = FE_RESET_R V2 0013
0005 FE_FETCH_R V1 CV0($char) 0013
0003 T2 = DO_ICALL
0004 T1 = FE_RESET_R T2 0013
0005 FE_FETCH_R T1 CV0($char) 0013
0006 INIT_FCALL 1 %d string("var_dump")
0007 INIT_FCALL 1 %d string("test")
0008 SEND_VAR CV0($char) 1
0009 V2 = DO_UCALL
0010 SEND_VAR V2 1
0009 T2 = DO_UCALL
0010 SEND_VAL T2 1
0011 DO_ICALL
0012 JMP 0005
0013 FE_FREE V1
0013 FE_FREE T1
0014 RETURN int(1)
LIVE RANGES:
1: 0005 - 0013 (loop)

View File

@@ -40,24 +40,24 @@ $_main:
0000 INIT_FCALL 2 %d string("range")
0001 SEND_VAL int(0) 1
0002 SEND_VAL int(6) 2
0003 V2 = DO_ICALL
0004 V1 = FE_RESET_R V2 0020
0005 FE_FETCH_R V1 CV0($number) 0020
0003 T2 = DO_ICALL
0004 T1 = FE_RESET_R T2 0020
0005 FE_FETCH_R T1 CV0($number) 0020
0006 INIT_FCALL 1 %d string("var_dump")
0007 INIT_FCALL 1 %d string("test")
0008 SEND_VAR CV0($number) 1
0009 V2 = DO_UCALL
0010 SEND_VAR V2 1
0009 T2 = DO_UCALL
0010 SEND_VAL T2 1
0011 DO_ICALL
0012 INIT_FCALL 1 %d string("var_dump")
0013 INIT_FCALL 1 %d string("test")
0014 T2 = CAST (string) CV0($number)
0015 SEND_VAL T2 1
0016 V2 = DO_UCALL
0017 SEND_VAR V2 1
0016 T2 = DO_UCALL
0017 SEND_VAL T2 1
0018 DO_ICALL
0019 JMP 0005
0020 FE_FREE V1
0020 FE_FREE T1
0021 RETURN int(1)
LIVE RANGES:
1: 0005 - 0020 (loop)

View File

@@ -58,15 +58,15 @@ MyClass::new:
; (after optimizer)
; %s
0000 CV0($bar) = RECV 1
0001 V2 = NEW 1 string("Random\\Engine\\Xoshiro256StarStar")
0001 T2 = NEW 1 string("Random\\Engine\\Xoshiro256StarStar")
0002 SEND_VAL int(123) 1
0003 DO_FCALL
0004 CV1($engine) = QM_ASSIGN V2
0005 V2 = NEW 2 (self) (exception)
0004 CV1($engine) = QM_ASSIGN T2
0005 T2 = NEW 2 (self) (exception)
0006 SEND_VAR CV1($engine) 1
0007 SEND_VAR CV0($bar) 2
0008 DO_FCALL
0009 RETURN V2
0009 RETURN T2
LIVE RANGES:
2: 0002 - 0004 (new)
2: 0006 - 0009 (new)

View File

@@ -33,28 +33,28 @@ $_main:
0000 INIT_FCALL 0 %d string("zend_test_nodiscard")
0001 DO_FCALL_BY_NAME
0002 INIT_FCALL 0 %d string("zend_test_nodiscard")
0003 V2 = DO_ICALL
0004 FREE V2
0003 T2 = DO_ICALL
0004 FREE T2
0005 INIT_FCALL 0 %d string("zend_test_nodiscard")
0006 V2 = DO_ICALL
0007 ASSIGN CV0($success) V2
0006 T2 = DO_ICALL
0007 ASSIGN CV0($success) T2
0008 INIT_FCALL 0 %d string("test")
0009 DO_FCALL_BY_NAME
0010 INIT_FCALL 0 %d string("test")
0011 V2 = DO_UCALL
0012 FREE V2
0011 T2 = DO_UCALL
0012 FREE T2
0013 INIT_FCALL 0 %d string("test")
0014 V2 = DO_UCALL
0015 ASSIGN CV1($obj) V2
0014 T2 = DO_UCALL
0015 ASSIGN CV1($obj) T2
0016 RETURN int(1)
test:
; (lines=3, args=0, vars=0, tmps=%d)
; (after optimizer)
; %s
0000 V0 = NEW 0 string("stdClass")
0000 T0 = NEW 0 string("stdClass")
0001 DO_FCALL
0002 RETURN V0
0002 RETURN T0
LIVE RANGES:
0: 0001 - 0002 (new)

View File

@@ -24,8 +24,8 @@ $_main:
0000 INIT_FCALL 2 %d string("random_int")
0001 SEND_VAL int(1) 1
0002 SEND_VAL int(2) 2
0003 V1 = DO_ICALL
0004 ASSIGN CV0($f) V1
0003 T1 = DO_ICALL
0004 ASSIGN CV0($f) T1
0005 INIT_FCALL 1 %d string("var_dump")
0006 T1 = BOOL_NOT CV0($f)
0007 SEND_VAL T1 1

View File

@@ -31,9 +31,9 @@ foo:
; (after optimizer)
; %sdce_006.php:5-8
0000 CV0($x) = RECV 1
0001 V2 = NEW 0 string("A")
0001 T2 = NEW 0 string("A")
0002 DO_FCALL
0003 CV1($a) = QM_ASSIGN V2
0003 CV1($a) = QM_ASSIGN T2
0004 ASSIGN_OBJ CV1($a) string("foo")
0005 OP_DATA CV0($x)
0006 RETURN null

View File

@@ -65,8 +65,8 @@ BB0:
; level=0
; children=(BB1, BB2, BB3)
0000 INIT_FCALL 0 %d string("rand")
0001 #2.V2 [long] = DO_ICALL
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10)
0001 #2.T2 [long] = DO_ICALL
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.T2 [long] int(10)
0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2
BB1:
@@ -111,8 +111,8 @@ BB0:
; level=0
; children=(BB1, BB2, BB3)
0000 INIT_FCALL 0 %d string("rand")
0001 #2.V2 [long] = DO_ICALL
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.V2 [long] int(10)
0001 #2.T2 [long] = DO_ICALL
0002 #3.T3 [long] RANGE[MIN..MAX] = MOD #2.T2 [long] int(10)
0003 JMPZ #3.T3 [long] RANGE[MIN..MAX] BB2
BB1:

View File

@@ -62,44 +62,44 @@ $_main:
0000 INIT_FCALL 1 %d string("var_dump")
0001 INIT_FCALL 1 %d string("testtrim1")
0002 SEND_VAL string(" boo ") 1
0003 V0 = DO_UCALL
0004 SEND_VAR V0 1
0003 T0 = DO_UCALL
0004 SEND_VAL T0 1
0005 DO_ICALL
0006 INIT_FCALL 1 %d string("var_dump")
0007 INIT_FCALL 1 %d string("testmin2first")
0008 SEND_VAL int(5) 1
0009 V0 = DO_UCALL
0010 SEND_VAR V0 1
0009 T0 = DO_UCALL
0010 SEND_VAL T0 1
0011 DO_ICALL
0012 INIT_FCALL 1 %d string("var_dump")
0013 INIT_FCALL 1 %d string("testmin2second")
0014 SEND_VAL int(5) 1
0015 V0 = DO_UCALL
0016 SEND_VAR V0 1
0015 T0 = DO_UCALL
0016 SEND_VAL T0 1
0017 DO_ICALL
0018 INIT_FCALL 1 %d string("var_dump")
0019 INIT_FCALL 1 %d string("testmin2_tmp")
0020 SEND_VAL int(5) 1
0021 V0 = DO_UCALL
0022 SEND_VAR V0 1
0021 T0 = DO_UCALL
0022 SEND_VAL T0 1
0023 DO_ICALL
0024 INIT_FCALL 1 %d string("var_dump")
0025 INIT_FCALL 1 %d string("teststrstr3first")
0026 SEND_VAL string("needles") 1
0027 V0 = DO_UCALL
0028 SEND_VAR V0 1
0027 T0 = DO_UCALL
0028 SEND_VAL T0 1
0029 DO_ICALL
0030 INIT_FCALL 1 %d string("var_dump")
0031 INIT_FCALL 1 %d string("teststrstr3second")
0032 SEND_VAL string("needle") 1
0033 V0 = DO_UCALL
0034 SEND_VAR V0 1
0033 T0 = DO_UCALL
0034 SEND_VAL T0 1
0035 DO_ICALL
0036 INIT_FCALL 1 %d string("var_dump")
0037 INIT_FCALL 1 %d string("teststrstr3third")
0038 SEND_VAL bool(false) 1
0039 V0 = DO_UCALL
0040 SEND_VAR V0 1
0039 T0 = DO_UCALL
0040 SEND_VAL T0 1
0041 DO_ICALL
0042 RETURN int(1)

View File

@@ -29,15 +29,15 @@ $_main:
; %s
0000 T1 = ISSET_ISEMPTY_CV (isset) CV0($badvar)
0001 JMPNZ T1 0006
0002 V3 = NEW 1 string("Exception")
0002 T3 = NEW 1 string("Exception")
0003 SEND_VAL%S string("Should happen") 1
0004 DO_FCALL
0005 THROW V3
0005 THROW T3
0006 JMP 0006
0007 V6 = NEW 1 string("Exception")
0007 T6 = NEW 1 string("Exception")
0008 SEND_VAL%S string("Should not happen") 1
0009 DO_FCALL
0010 THROW V6
0010 THROW T6
0011 FAST_RET T5
EXCEPTION TABLE:
0006, -, 0007, 0011

View File

@@ -32,18 +32,18 @@ $_main:
; %s
0000 T2 = ISSET_ISEMPTY_CV (isset) CV0($badvar)
0001 JMPNZ T2 0008
0002 V4 = NEW 1 string("Exception")
0002 T4 = NEW 1 string("Exception")
0003 SEND_VAL%S string("Should happen") 1
0004 DO_FCALL
0005 THROW V4
0005 THROW T4
0006 CV1($e) = CATCH string("Throwable")
0007 ECHO string("foo")
0008 T6 = FAST_CALL 0010
0009 JMP 0015
0010 V7 = NEW 1 string("Exception")
0010 T7 = NEW 1 string("Exception")
0011 SEND_VAL%S string("Should not happen") 1
0012 DO_FCALL
0013 THROW V7
0013 THROW T7
0014 FAST_RET T6
0015 RETURN int(1)
EXCEPTION TABLE:

View File

@@ -28,6 +28,6 @@ test:
; (after optimizer)
; %s:2-6
0000 INIT_FCALL_BY_NAME 0 string("test2")
0001 V1 = DO_FCALL_BY_NAME
0002 CV0($var) = QM_ASSIGN V1
0001 T1 = DO_FCALL_BY_NAME
0002 CV0($var) = QM_ASSIGN T1
0003 RETURN CV0($var)

View File

@@ -51,14 +51,14 @@ bar:
; (lines=9, args=0, vars=3, tmps=2)
; (after optimizer)
; %s
0000 V3 = FE_RESET_R CV0($a) 0007
0001 FE_FETCH_R V3 CV1($v) 0007
0002 V4 = FE_RESET_R CV1($v) 0005
0003 FE_FETCH_R V4 CV2($v2) 0005
0000 T3 = FE_RESET_R CV0($a) 0007
0001 FE_FETCH_R T3 CV1($v) 0007
0002 T4 = FE_RESET_R CV1($v) 0005
0003 FE_FETCH_R T4 CV2($v2) 0005
0004 JMP 0003
0005 FE_FREE V4
0005 FE_FREE T4
0006 JMP 0001
0007 FE_FREE V3
0007 FE_FREE T3
0008 RETURN null
LIVE RANGES:
3: 0001 - 0007 (loop)

View File

@@ -30,27 +30,26 @@ $_main:
; (after optimizer)
; %ssccp_032.php:1-15
0000 INIT_FCALL 0 %d string("test")
0001 V2 = DO_UCALL
0002 V1 = FE_RESET_R V2 0009
0003 FE_FETCH_R V1 CV0($x) 0009
0001 T2 = DO_UCALL
0002 T1 = FE_RESET_R T2 0009
0003 FE_FETCH_R T1 CV0($x) 0009
0004 INIT_FCALL 1 %d string("var_export")
0005 SEND_VAR CV0($x) 1
0006 DO_ICALL
0007 ECHO string("\n")
0008 JMP 0003
0009 FE_FREE V1
0009 FE_FREE T1
0010 RETURN int(1)
LIVE RANGES:
1: 0003 - 0009 (loop)
test:
; (lines=5, args=0, vars=0, tmps=1)
; (lines=4, args=0, vars=0, tmps=0)
; (after optimizer)
; %ssccp_032.php:2-9
0000 GENERATOR_CREATE
0001 YIELD null
0002 T0 = YIELD_FROM array(...)
0003 FREE T0
0004 GENERATOR_RETURN null
0002 YIELD_FROM array(...)
0003 GENERATOR_RETURN null
NULL
3

View File

@@ -39,5 +39,5 @@ Test::getInt2:
; (lines=2, args=0, vars=0, tmps=1)
; (after optimizer)
; %s
0000 V0 = QM_ASSIGN int(42)
0001 RETURN V0
0000 T0 = VERIFY_RETURN_TYPE int(42)
0001 RETURN T0

View File

@@ -35,30 +35,29 @@ var_dump($res1);
?>
--EXPECTF--
$_main:
; (lines=18, args=0, vars=2, tmps=%d)
; (lines=17, args=0, vars=2, tmps=%d)
; (after optimizer)
; %s:1-27
0000 V2 = NEW 0 string("Other")
0000 T2 = NEW 0 string("Other")
0001 DO_FCALL
0002 ASSIGN CV0($o) V2
0002 ASSIGN CV0($o) T2
0003 INIT_FCALL 1 %d string("_test1")
0004 SEND_VAL int(5) 1
0005 T2 = DO_UCALL
0006 INIT_METHOD_CALL 1 CV0($o) string("foo")
0007 SEND_VAL_EX T2 1
0008 V3 = DO_FCALL
0009 T2 = QM_ASSIGN V3
0010 INIT_STATIC_METHOD_CALL 1 string("Other") string("bar")
0011 SEND_VAL T2 1
0012 V2 = DO_UCALL
0013 ASSIGN CV1($res1) V2
0014 INIT_FCALL 1 %d string("var_dump")
0015 SEND_VAR CV1($res1) 1
0016 DO_ICALL
0017 RETURN int(1)
0008 T2 = DO_FCALL
0009 INIT_STATIC_METHOD_CALL 1 string("Other") string("bar")
0010 SEND_VAL T2 1
0011 T2 = DO_UCALL
0012 ASSIGN CV1($res1) T2
0013 INIT_FCALL 1 %d string("var_dump")
0014 SEND_VAR CV1($res1) 1
0015 DO_ICALL
0016 RETURN int(1)
LIVE RANGES:
2: 0001 - 0002 (new)
2: 0010 - 0011 (tmp/var)
2: 0009 - 0010 (tmp/var)
_test1:
; (lines=4, args=1, vars=1, tmps=%d)

View File

@@ -19,8 +19,8 @@ L0014 0000 CV0($baz) = RECV 1
L0015 0001 INIT_FCALL %d %d string("var_dump")
L0015 0002 INIT_FCALL %d %d string("strrev")
L0015 0003 SEND_VAR CV0($baz) 1
L0015 0004 V1 = DO_ICALL
L0015 0005 SEND_VAR V1 1
L0015 0004 T1 = DO_ICALL
L0015 0005 SEND_VAL T1 1
L0015 0006 DO_ICALL
L0016 0007 RETURN null
prompt> [User Class: Foo\Bar (2 methods)]
@@ -44,9 +44,9 @@ prompt> [Context %s (9 ops)]
$_main:
; (lines=9, args=0, vars=0, tmps=%d)
; %s:1-21
L0018 0000 V0 = NEW 0 string("Foo\\Bar")
L0018 0000 T0 = NEW 0 string("Foo\\Bar")
L0018 0001 DO_FCALL
L0018 0002 INIT_METHOD_CALL 1 V0 string("Foo")
L0018 0002 INIT_METHOD_CALL 1 T0 string("Foo")
L0018 0003 SEND_VAL_EX string("test \"quotes\"") 1
L0018 0004 DO_FCALL
L0019 0005 INIT_FCALL %d %d string("foo")

View File

@@ -25,8 +25,8 @@ L0014 0000 CV0($baz) = RECV 1
L0015 0001 INIT_FCALL %d %d string("var_dump")
L0015 0002 INIT_FCALL %d %d string("strrev")
L0015 0003 SEND_VAR CV0($baz) 1
L0015 0004 V1 = DO_ICALL
L0015 0005 SEND_VAR V1 1
L0015 0004 T1 = DO_ICALL
L0015 0005 SEND_VAL T1 1
L0015 0006 DO_ICALL
L0016 0007 RETURN null
prompt> L0015 0001 INIT_FCALL %d %d string("var_dump")